|
Cookbook /
WikiSh Examples and ApplicationsThis page gives examples or mini-applications of WikiSh in action... Note that examples surrounded by There is a live test site available to try out WikiSh. Many of the examples below already contain links, but you can also go to the control panel for more generic testing at http://pmwiki.qdk.org/pmwiki.php/WikiSh/ControlPanel. Feel free to use other pages on that site to test out other functionality as well. Allow people to sign up for "slots" in a tableSay you wanted teachers to sign up for study hall coverage or your book club wants people to sign up for various parts of the meal for the next 3 meetings. It would be nice to have a signup form that allows them to just click on a slot and have their name filled in automatically.
Put this source in a page somewhere:
{(wikish source {$FullName}#MkForm)}
(:if false:)
[[#MkForm]]
wikish_form QUICKFORM PROCESS
# Process any signups...
for i in ${!cell_*}
do
if test -n ${i}
then
if test ${${i}} == 'X'
then
if test {$:${i}} == {$AuthId}
then
writeptv {$FullName} ${i}=
wikish_form REDIRECT target={$FullName}
else
echo "Unable to UNsign for someone besides yourself."
fi
else
writeptv {$FullName} ${i}={$AuthId}
wikish_form REDIRECT target={$FullName}
fi
fi
done
# Now draw the table
echo "(:table border=1:)"
for r in '' 8am 9am 10am 11am 12pm
do
for c in '' Mon Tues Wed Thur Fri
do
if test -z ${r}
then
echo "(:cell align=center:)${c}"
else
if test -z ${c}
then
echo "(:cellnr valign=center align=center:)${r}"
else
echo "(:cell valign=center align=center:)"
if test -n {$:cell_${c}_${r}}
then
echo "{$:cell_${c}_${r}} (:input submit cell_${c}_${r} 'X':)"
else
echo "(:input submit cell_${c}_${r} 'Sign Up':)"
fi
fi
fi
done
done
echo "(:tableend:)\n(:input end:)"
[[#MkFormEnd]]
(:ifend:)
Create a page from a form interface, choosing the appropriate template from a listSometimes a single template is not sufficient -- users need the capability of choosing from different templates. This little form allows users to enter a group and page and choose a template to create a new page. The list of templates is created dynamically based on the contents of the group Templates.*. The form might look like this (your templates will be different):
(:linebreaks:)
{(wikish MkNewPage)}
(:table:)
(:cellnr align=right:)Group:
(:cell align=left:)(:input text name=group:)
(:cellnr align=right:)Title / Pagename:
(:cell align=left:)(:input text name=pn:)
(:cellnr align=right valign=middle:)Template:
(:cell align=left:){(wikish RadioTemplates)}
(:tableend:)
(:input submit name=submit value=Create:)
(:input end:)
function RadioTemplates
{
set -s LIST = normal
for i in Templates.*
do
if test -n "{${i}$:MenuText}"
then
echo '(:input radio name=template value="${i}":){${i}$:MenuText} (${i})'
else
echo '(:input radio name=template value="${i}":)${i}'
fi
done
}
function MkNewPage
{
wikish_form quickform process
if test -z "${submit}"
then
exit
fi
if test -z "${group}"
then
echo "%red%ERROR: You must enter a group name%%"
exit
fi
if test -z "${pn}"
then
echo "%red%ERROR: You must enter a title / pagename%%"
exit
fi
set -s newpn = `sed 's/[^a-zA-Z0-9_.-]//g' - "${pn}"`
if test -f "${group}.${newpn}"
then
echo "%red%ERROR: Page [[${group}.${newpn}]] already exists%%"
exit
fi
echo "("":title ${pn}:"")" >${group}.${newpn}
if test -n ${template}
then
grep -v MenuText ${template} >>${group}.${newpn}
fi
#echo "[[${group}.${newpn}|+]]" >>Test.NewPageList
wikish_form redirect target=${group}.${newpn}?action=edit
}
(:MenuText:This Text will appear verbatim in the menu of templates:)
*.*:read,create View the differences between a page at a given point in time compared to the current version (form-based)If you view page history normally it shows you a diff output between each revision. Sometimes you want to be able to do a comparison with a revision several back and the current without seeing the in-between diffs. This form allows provides this functionality.
{(wikish_form quickform process)}
page: (:input text pn:)
when: (:input text when:)
(:input submit View View:)
{(wikish source {$FullName}#ViewDiff)}
(:if false:)
[[#ViewDiff]]
if test -n ${View}
then
if test -z "${pn}" || ! test -f "${pn}"
then
echo "ERROR: Must enter a valid page first"
exit
fi
if test -z '`ftime "%s" "${when}"`'
then
echo "ERROR: Must enter a date/time in the 'when' field"
exit
fi
#echo "DEBUG:
echo "\n----\n"
diff ${pn}@`ftime "%s" "${when}"` ${pn}
echo "\n----\n"
fi
[[#ViewDiff]]
(:ifend:)
if ($pagename == 'Test.Diff' && $action=='browse') {
$DiffFunction = 'mydiff';
include_once("Text/Diff.php");
include_once("Text/Diff/Renderer.php");
include_once("Text/Diff/Renderer/inline.php");
function mydiff($text1, $text2)
{
$diff = &new Text_Diff(explode("\n", $text1), explode("\n", $text2));
$renderer = &new Text_Diff_Renderer_inline();
return($renderer->render($diff));
}
}
View a historical revision of a page as of a certain time - accessed via a formSometimes it is convenient to be able to view a given revision of a page (a 'snapshot' at a certain time) from a simple form-based interface.
{(wikish_form quickform process)}
page: (:input text pn:)
when: (:input text when:)
(:input submit View View:)
{(wikish source {$FullName}#ViewHistory)}
(:if false:)
[[#ViewHistory]]
if test -n ${View}
then
if test -z "${pn}" || ! test -f "${pn}"
then
echo "ERROR: Must enter a valid page first"
exit
fi
if test -z '`ftime "%s" "${when}"`'
then
echo "ERROR: Must enter a date/time in the 'when' field"
exit
fi
#echo "DEBUG:
echo "\n----\n"
cat ${pn}@`ftime "%s" "${when}"`
echo "\n----\n"
fi
[[#ViewHistoryEnd]]
(:ifend:)
page: when:
Compare and use historical revisions of pagesPmwiki stores old revisions of pages whenever an edit is made. By looking at the "History" link you can see each of those revisions with the relative changes. From that view you can easily restore any of the old versions of the page. But sometimes you want to compare 2 older versions or a much older version directly with the current version without having to understand each of the intervening revisions. Or perhaps you want the older version of the file but in a different page rather than the current. Obviously this can be accomplished via multiple copy/paste operations, but WikiSh makes it much easier: Comparing the version of the page from 3 days ago with the version 1 day ago in the control paneldiff Page@`ftime "%s" "3 days ago"` Page@`ftime "%s" "yesterday"` Copying the version of a page from a certain date to a new page without altering the most up-to-date version of that pagecat Mygroup.MyPage@`ftime "%s" "January 1, 2009 9:39am"` >GroupB.NewPage Restoring several pages from the version they had at a certain time (for instance, if a spammer struck several pages at once)
for i in Page1 Page2 Page3
do
cat ${i}@`ftime "%s" "01/01/2009 12:57pm"` >${i}
done
Create a group (form-based) and protect it immediately
(:if name HomeGroups.Create:) *:create,read *.GroupAttributes:attr,forceedit (:ifend:)
{(wikish_form QUICKFORM PROCESS)}
New Group:
(:input text name=GroupName:)\\
(:input submit name=submit value=Create:)
(:input end:)
{(wikish source {$FullName}#validate)}
(:if false:)
[[#validate]]
if test -n "${submit}"
then
if ! test -n "${GroupName}"
then
echo "ERROR: Must specify the new group name."
exit
fi
if test -f ${GroupName}.Page1 || test -f ${GroupName}.Page2
then
echo "ERROR: ${GroupName} already exists."
exit
fi
if test -z "$AuthId"
then
echo "ERROR: You must be [[{$FullName}?action=login|logged in]] as a valid user before creating a group."
exit
fi
echo "Creating New Group...\\\n\\\n"
cp HomeGroup.Page1 ${GroupName}
echo "" >${GroupName}.GroupAttributes
chmod --read:id:$AuthId ${GroupName}.GroupAttributes
echo "\\\n\\\n...DONE! Click [[${GroupName}.Page1|here]] to go to your new group - only you have permission to read/edit."
fi
[[#validateend]]
(:if:)
New Group:
Write to a PTV by URL
{(wikish --expandvars writeptv ${!page} ${!var}=${!value})}
http://www.example.com/pmwiki/pmwiki.php?n=Test.Write2PTV?page=Test.X?var=myvar?value=myvalue
(:myvar:myvalue:)
Self-Register for a site using AuthUser
(:if name Test.Signup:) SiteAdmin.AuthUser:read,append,forceread,forceedit (:ifend:)
{(wikish source {$FullName}#signup)}
Sign up for access to this wiki:\\
Username: (:input text username:)\\
Password: (:input password password:)\\
(:input submit submit Submit:)
(:input end:)
(:if false:)
[[#signup]]
wikish_form quickform process
if test -z "${submit}"
then
exit
fi
if grep -q "^${username}:" SiteAdmin.AuthUser
then
echo "%red%That user already exists. Contact your administrator to change your password.%%"
exit
fi
if test "${username}" ~= "/[^a-z0-9_]/i"
then
echo "%red%Only alphabetic characters, numeric digits, and underscore are allowed in the username.%%"
exit
fi
if test "${password}" ~= "/ /"
then
echo "%red%No spaces in the password.%%"
exit
fi
# OK, I think we're legitimate at this point - go ahead and add it to the AuthUser table
echo "${username}:`crypt ${password}`" >>SiteAdmin.AuthUser
echo "%red%Success%%"
[[#signupend]]
(:ifend:)
Sign up for access to this wiki:
Produce multiple pagelists with the same selection criteriaThe request it to produce 3 pagelists with the same selection criteria, but each list to be displayed in a different order. See here for the initial request. See here for PM's response giving the $PagelistCacheDir solution that is probably much faster than this.
{(wikish set -s pagelist = "`pagelist wrap=inline $:obsolete=-yes`")}
(:table:)
(:cellnr:)Sorted by creation time (most recent first)
(:cell:)Sorted by modification time (most recent first)
(:cell:)Sorted alphabetically
(:cellnr:)(:pagelist name=${pagelist} fmt=#bygroup order=-ctime :)
(:cell:)(:pagelist name=${pagelist} fmt=#bygroup order=-time :)
(:cell:)(:pagelist name=${pagelist} fmt=#bygroup :)
(:tableend:)
Automatically reply to email messages in a given formatFor a beta test I was running of wikibox I got tired of having to load up a different user's email, open the new email, and reply every time I wanted to moderate a message. About 90% of the time I wanted the moderator to approve the message but I wanted it to happen automatically. The script below enabled me to automatically reply to messages, altering the subject and body as necessary, simply by loading a single page. (I could then load this page periodically via cron if I wanted it to go perpetually or else just run the wget by hand to quickly load the page.)
(:linebreaks:)
{(wikish Moderate)}
function Moderate
{
echo "Checking..."
# Loop through, getting a message, using the profile "moderator" as long as that mailbox has any messages
while fetchmail --profile:moderator --body:body --from:from --subject:subject
do
echo "====\n'''from=`sed -e 's/</</g' -e 's/>/>/g' - '${from}'`, subject=${subject}'''"
# Make sure the subject has the word "confirm" in it before replying - indicates it's a wikibox message
if grep -qi CONFIRM - "${subject}"
then
# Set the moderator's oh-so-secret password to "xyz" in the body of the message
set -s newbody = "`sed 's/wikibox-password:/wikibox-password:xyz/' - '${body}'`"
# Update the log of all messages we've sent from this script
echo "TO: ${from}, SUBJECT: ${subject}" >>WikiBox.SentLog
# Send the message, giving appropriate messages upon success or failure
if mailx -f wikibox_mod@qdk.org -t "${from}" -c "username@example.com" -s "${subject}" - "${newbody}"
then
echo "Mail Sent."
else
echo "ERROR: Mail may not have been sent."
fi
else
# Message was not from wikibox - error. Put the error in an error log page.
echo "ERRORS. See [[WikiBox.Moderate-Errors]]
echo "====\n'''FROM:''' ${from}\n'''TO:''' ${to}\n'''SUBJECT:''' ${subject}\n${body}" >>WikiBox.Moderate-Errors
fi
done
echo "Done Checking..."
# Close the POP3 handle so messages actually get deleted
fetchmail --profile:moderator --close
}
Do a pagelist which includes the selection criteria of multiple pagelists.For instance, only a single
{(wikish pagelist sep=\n link=Category.A wrap=inline | cat >Temp.A;
pagelist sep=\n link=Category.B wrap=inline | cat >>Temp.A;
pagelist wrap=inline fmt=#simple name=`sort --uniq --newline:, Temp.A`)}
function CategoryByWildcards
{
if test -f Temp.A
then
rm Temp.A
fi
for i in
do
pagelist sep=\n link= wrap=inline | cat >>Temp.A
done
sort -u —newline:, Temp.A
}
{(wikish pagelist wrap=inline fmt=#simple name=`CategoryByWildcards Category.[AB]`)}
or
{(wikish pagelist wrap=inline fmt=#simple name=`CategoryByWildcards Category.A Category.B`)}
(:linebreaks:)
{(wikish pagelist sep=\n link=Category.A wrap=inline | cat >Temp.A)}
After A
{(cat Temp.A)}
{(wikish pagelist sep=\n link=Category.B wrap=inline | cat >>Temp.A)}
After B
{(cat Temp.A)}
Sorted
{(sort -u Temp.A)}
Sep by ,
{(sort --newline:, -u Temp.A)}
Pagelist
{(wikish pagelist wrap=inline fmt=#simple name=`sort --uniq --newline:, Temp.A`)}
function PagelistUnion
{
if test -f Temp.A
then
rm Temp.A
fi
for i in ${*}
do
pagelist sep=\n ${i} wrap=inline | cat >>Temp.A
done
sort -u --newline:, Temp.A
}
{(wikish pagelist wrap=inline fmt=#simple name=`PagelistUnion link=Category.A link=Category.B name=Test.A*`)}
Pagelist with redirect for single page returns
{(wikish set -s pglst = '`pagelist wrap=inline sep=\n name=Test.NewPage`';
if test -n "${pglst}" && test `wc -lq - "${pglst}"` -eq 1; then; wikish_form redirect target=${pglst};
else; echo "${pglst}"; fi)}
Look for a page with the word "password" on it in the Site group
grep --line_prefix:"'''PAGENAME:''' " Password Site.* OK, so it's a stretch as an application - think of it more as an example... :-) Provide a form in which a title can be entered and a page will be automatically createdThis allows accents, better specification of upper/lower case, etc and the pagename will be related but somewhat abstracted. See http://pmichaud.com/pipermail/pmwiki-users/2008-July/051789.html for the description of the problem.
(:linebreaks:)
{(wikish MkNewPage)}
Make new page: (:input text name=pn:)
(:input submit name=submit value=Create:)
(:input end:)
List of pages created:\\
(:include Test.NewPageList:)
function MkNewPage
{
wikish_form quickform process
if test -z "${submit}"
then
exit
fi
if test -z "${pn}"
then
echo "ERROR: You must enter a title"
exit
fi
set -s newpn = `sed 's/[^a-zA-Z0-9_.-]/_/g' - "${pn}"`
if test -f "${newpn}"
then
echo "ERROR: ${newpn} already exists"
exit
fi
echo "("":title ${pn}:"")" >${newpn}
echo "[[${newpn}|+]]" >>Test.NewPageList
wikish_form redirect target=${newpn}?action=edit
}
Allow redirects from a specific group to elsewhere in the wiki (ala TinyURL)Create a list of pages within one group which will be aliases for other pages elsewhere. See RedirectMap for a non-wikish solution.
Tiny.Short::MyVeryLongGroupNameThatIAlwaysWriteWrong.ALongPageThatShouldHaveAShorterName Tiny.ApproveUrl::Test.ApproveUrl Tiny.CL::WikiSh.ControlPanel
{(wikish set -s target = "`grep '{*$FullName}:' Tiny.List | sed
's/^.*:://'`"; if test -n "${target}" && test `wc -l - ${target}` -eq
1; then; wikish_form redirect target=${target}; else; echo "Could not
redirect from @@{*$FullName}@@ to @@${target:-Nonexistent Target}@@"; fi)}
set -s target = "`grep '{*$FullName}:' Tiny.List | sed 's/^.*:://'`"
if test -n "${target}" && test `wc -l - ${target}` -eq 1
then
wikish_form redirect target=${target}
else
echo "Could not redirect from @@{*$FullName}@@ to @@${target:-Nonexistent Target}@@@"
fi
Create numbered sub-pagesWhatever page this wikish script is placed on will now have a link to create a new subpage named by suffixing "-01", "-02", etc. It can be used in many instances, but my specific need was to have something in my ViewTemplate for my wikiforms application so I could have additional pages with other information besides that held in the fields in the 'database'.
{(wikish set -s lastpage = "`pagelist sep=\n name={*$FullName}-[0-9][0-9] | tail -n 1`"; (NO NEWLINE)
if test -z "${lastpage}"; then; set -s newpage = "{*$FullName}-01"; else; (NO NEWLINE)
set newnum = ${lastpage#*-} + 1; set -s newstr = 00${newnum}; set -s newpage = "{*$FullName}-${newstr,-2}"; (NO NEWLINE)
fi; echo "[[${newpage}?action=edit|Create Sub-Page]]")}
(:pagelist wrap=inline name={*$FullName}-[0-9][0-9] fmt=#title2:)
{(wikish source {*$FullName}#SubPageLink)}
...
(:if false:)
[[#SubPageLink]]
set -s lastpage = "`pagelist sep=\n name={*$FullName}-[0-9][0-9] | tail -n 1`"
if test -z "${lastpage}"
then
set -s newpage = "{*$FullName}-01"
else
set newnum = ${lastpage#*-} + 1
set -s newstr = 00${newnum}
set -s newpage = "{*$FullName}-${newstr,-2}"
fi
echo "[[${newpage}?action=edit|Create Sub-Page]]"
Validate form data and collect it on a separate page in a tableThis simply demonstrates a very simple example of validating data from a form (server-side) and then placing the data in a table on another page to collect the data.
{(wikish_form quickform process)}
|| width=50%
|| FIRST NAME:||(:input text name=fname:) ||
|| LAST NAME:||(:input text name=lname:) ||
|| AGE:||(:input text name=age:) ||
|| FAVORITE:||(:input radio cartoon Fred:) Fred Flinstone\\
(:input radio cartoon Barney:) Barney Rubble||
(:input submit name=Submit value=Submit:)
(:input end:)
{(wikish source {*$FullName}#Validate)}
(:if false:)
[[#Validate]]
#echo "Validating..."
if test -z ${Submit}
then
exit
fi
set err = 0
set -s out = Test.FormData
# Validate that the names have a capital letter as a 1st character
if test ${fname:0:1} < 'A' || test ${fname:0:1} > 'Z'
then
echo "ERROR: You must capitalize your first name. Form not processed."
set err = 1
fi
if test ${lname:0:1} < 'A' || test ${lname:0:1} > 'Z'
then
echo "ERROR: You must capitalize your last name. Form not processed."
set err = 1
fi
# Validate that the person is 18 or older
if test ${age} -lt 18
then
echo "ERROR: You must be 18 years of age to vote. Form not processed."
set err = 1
fi
if test -z ${cartoon}
then
echo "ERROR: You must select either Fred or Barney. Form not processed."
set err = 1
fi
# If no errors then write out this line of data to the data output page
if test ${err} -eq 0
then
echo "||${fname} ${lname} || ${age}||${cartoon}||" >>${out}
echo "One vote processed for ${cartoon} -- see [[${out}]]"
fi
[[#EndValidate]]
(:ifend:)
Assist administrators with approving URLsApproveUrls allows an administrator to limit the external URLs placed on his site. However, it requires careful follow-up by the administrator to make sure valid URLs are approved. This script facilitates doing a global check of what URLs have not been approved so they can either be deleted or approved by the administrator.
(:linebreaks:)
{(wikish grep --debug:1 --line_prefix:"[[PAGENAME]]::" http (NO NEWLINE)
`pagelist group=-PmWiki,-Site,-SiteAdmin list=normal http sep=\n` (NO NEWLINE)
| sed "s/:.*(http[^]\\|\\s,]*)(?:.*?$)/:$1/")}
$UnapprovedLinkCountMax = 500; The page source itself will look like this:
{(wikish source {$FullName}#funky)}
(:if false:)
[[#funky]]
set -s out = Test.ToApprove # Change this pagename to put a static list of all links on that page
rm Virtual.X
grep --line_prefix:"PAGENAME:" 'https?:\/\/' `pagelist group=-PmWiki,-Site,-SiteAdmin list=normal http sep=\n` (NO NEWLINE)
| while read --IFS:: pn line
do
sed 's/http/\n${pn}:http/g' - "${line}" | grep -F '${pn}:http' >>Virtual.X
done
sed 's/^(\S+:https?:\/\/[^]\|?\/\&\s]+).*$/$1/' Virtual.X | while read --IFS:: pn line
do
if ! grep -qF " ${line}" SiteAdmin.ApprovedUrls
then
echo "||[[${pn}]] ||x - ${line} ||" >>Virtual.Out
else
echo "||[[${pn}]] ||${line} ||" >>Virtual.Out
fi
done
cp Virtual.Out ${out}
echo 'The list of links has been placed in the page [[${out}]]. Please go there and approve links.'
#wikish_form redirect target=${out}
rm Virtual.X
[[#endfunky]]
(:ifend:)
Redirect to a given page via a button (see ButonLink)
{(wikish_form quickform process)}
(:input submit name=gohome value="Go To Pmwiki Homepage":)
(:input end:)
{(wikish if test -n ${gohome}; then; wikish_form redirect target=pmwiki/pmwiki; fi)}
{(wikish_form quickform process)}
(:input submit button "Projects" value="Projects":)
(:input submit button "Products" value="Products":)
(:input submit button "PO" value="PO":)
(:input end:)
{(wikish if test ${button} == "Projects"; then; wikish_form redirect target={$FullName}?action=proj; fi)}
{(wikish if test ${button} == "Products"; then; wikish_form redirect target={$FullName}?action=products; fi)}
{(wikish if test ${button} == "PO"; then; wikish_form redirect target={$FullName}?action=PO; fi)}
(:if equal {$action} Projects:)
handle projects here
(:if equal {$action} Products:)
handle products here
(:if equal {$action} PO:)
handle PO here
(:ifend:)
{(wikish_form quickform process)}
(:input submit button "Projects" value="Projects":)
(:input submit button "Products" value="Products":)
(:input submit button "PO" value="PO":)
(:input end:)
(:if equal ${button} Projects:)
handle projects here
(:if equal ${button} Products:)
handle products here
(:if equal ${button} PO:)
handle PO here
(:ifend:)
Allow a given user to log in and automatically be taken to the appropriate home page
{(wikish set -s LIST = normal; for i in Client.*; do; if test -r ${i}; then; wikish_form redirect target=${i}; (JOIN THIS LINE)
exit; fi; done; wikish_form redirect target={$FullName}?action=login)}
{(wikish source {$FullName}#GotoClient)}
(:if false:)
[[#GotoClient]]
set -s LIST = normal
for i in Client.*
do
if test -r ${i}
then
wikish_form redirect target=${i}
exit
fi
done
wikish_form redirect target={$FullName}?action=login
[[#EndGotoClient]]
(:ifend:)
set -s LIST = normal # Make sure the Client.* doesn't include RecentChanges, other system pages
for i in Client.* # Loop through every page in the Client group
do
if test -r ${i} # If the current Client.X page is readable...
then
wikish_form redirect target=${i} # Redirect to it
exit # and stop processing this script
fi
done
# If I got here then there are NO pages which are readable -- present a login form to allow the
# user to enter another password
wikish_form redirect target={$FullName}?action=login
Sum up many PTVs named var1, var2, var3, ..., var30
{earlymx(wikish source Sum#totalit)}
And here is the official total: {$total}
(:if false:)
[[#totalit]]
set i = 1
set --pv total = 0
while test ${i} -le 30
do
set --pv total += {$:var${i}}
echo "running total ${i} = $total\\\n"
set i ++
done
echo total = $total
[[#totalitend]]
(:if:)
Create test data for the Summing Variables example above.
{earlymx(wikish_button A "Sum Them")(wikish source Sum#totalit)}
{earlymx(wikish_button B "Make List")(wikish source Sum#makevars)}
(:comment BELOWTHIS:)
And here is the official total: {$total}
(:if false:)
[[#makevars]]
set RANDOM_MAX = 10
set RANDOM_MIN = 0
set i = 1
while test ${i} -le 30
do
echo "(:var${i}:${RANDOM}:)" >WikiSh.Sum>BELOWTHIS
set i ++
done
[[#makevarsend]]
[[#totalit]]
set i = 1
set --pv total = 0
while test ${i} -le 30
do
set --pv total += {$:var${i}}
echo "running total ${i} = $total\\\n"
set i ++
done
echo total = $total
[[#totalitend]]
(:if:)
====
DEBUG
(:messages:)
Make a VERY rough shopping cart (can be beautified fairly trivially)
001:Chair:17.89 002:Table:79.23 003:Rug:50.01 004:Door:129.01
{(wikish_button a "Generate Form")(wikish source {$FullName}#genform)}
(:if false:)
[[#ValidateForm]]
if test ${Checkout} != "Checkout"
then
exit
fi
set nogood = 0
set totalprice = 0
set -s orderpage = Shop.Order
echo "(:linebreaks:)" >${orderpage}
while read --IFS:: ItemNo ItemName ItemCost <Items
do
if ! test ${Item${ItemNo}} ~= "/^\d*$/"
then
echo "ERROR: Item Number ${ItemNo} had a non-numeric quantity." >>${orderpage}
set nogood = 1
else
if test -z ${Item${ItemNo}}
then
set Item${ItemNo} = 0
fi
if test ${Item${ItemNo}} -gt 0
then
set extcost = ${Item${ItemNo}} * ${ItemCost}
set totalprice += ${extcost}
echo "${Item${ItemNo}} items of ${ItemName} (item number ${ItemNo}): ${extcost}" >>${orderpage}
fi
fi
done
if test ${nogood} -eq 1
then
echo "Error invalid. Please fix errors."
else
echo "Total Price for entire order: ${totalprice}" >>${orderpage}
wikish_form target=${orderpage} REDIRECT
fi
[[#endValidateForm]]
[[#genform]]
set -s formpage = Form
set -s openparen = '('
set -s closeparen = ')'
echo "{(wikish_form QUICKFORM PROCESS)}" >${formpage}
while read --IFS:: ItemNo ItemName ItemCost <Items
do
echo "${ItemName}: (:input text name=Item${ItemNo}:)\\" >>${formpage}
done
echo "${openparen}:input submit Checkout Checkout:${closeparen}" >>${formpage}
echo "${openparen}:input end:${closeparen}" >>${formpage}
# (the following 2 lines should be combined into 1
echo "${openparen}:if false:${closeparen}\n{${openparen}wikish source
Code#ValidateForm${closeparen}}\n${openparen}:if:${closeparen}" >>${formpage}
[[#genformend]]
(:if:)
Make a "static" pagelist, doing selection by title by regular expression
read --restoreset # this will not cause an error if there is nothing to restore
if test -z `read --status`
then
echo "Generating list of files to work off of..."
ls --list:normal >Tmp
fi
set -s output = "Foo" # CHANGE THIS VALUE IF YOU WANT YOUR OUTPUT TO GO TO A DIFFERENT PAGE
set -s titlevar = "{$" # Must build the variable in 2 steps or else other markup rules
set -s titlevar .= "Title}" # will substitute it before we can use it
set -s LIST = normal # don't include pages like RecentChanges, AllRecentChanges, PmWiki.*, etc.
while read fn <Tmp
do
#echo "Processing page ${fn}"
set -s REFPAGE = ${fn}
set -s title = ${titlevar}
if test ${title} ~= '/^[ABC]/'
then
echo "FOUND: ${fn} (${title})"
echo ${fn} >>${output} # CHANGE THIS LINE IF YOU WANT THE OUTPUT IN A DIFFERENT FORMAT
else
echo "NOT FOUND: ${fn} (${title})"
fi
set -s REFPAGE = ""
if test ${SECONDSLEFT} -lt 7 # allow 7 seconds for initial compile time plus time to process next file
then
read --saveset
echo "You will need to reinvoke this script to complete. You have finished" `read --status` "files out of" `read --linecount`
exit
fi
done
echo "COMPLETED! Please find your output in ${output}."
read --clearset # Make sure it's all cleared out for the end
Make a "static" list of pages with titles. This list can then be used for a faster pagelist.
Pagelist of titles starting with A
(:pagelist fmt=#title name={(wikish grep -i "^\s*A" WikiSh.PageList | cut --newline:, -d# -f2)}:)
Pagelist of titles starting with B
(:pagelist fmt=#title name={(wikish grep -i "^\s*B" WikiSh.PageList | cut --newline:, -d# -f2)}:)
set -s output = "WikiSh.PageList" # CHANGE THIS VALUE IF YOU WANT YOUR OUTPUT TO GO TO A DIFFERENT PAGE
read --restoreset # this will not cause an error if there is nothing to restore
if test -z `read --status`
then
echo "Generating list of files to work off of..."
ls --list:normal >Tmp
echo "--> Static pagelist last updated:" `ftime` >${output}
fi
set -s titlevar = "{$" # Must build the variable in 2 steps or else other markup rules
set -s titlevar .= "Title}" # will substitute it before we can use it
set -s PAGEVAR = 'pre' # In processing ${titlevar} WikiSh variables must be processed BEFORE PVs
while read fn <Tmp
do
#echo "Processing page ${fn}"
set -s REFPAGE = ${fn}
echo "${titlevar}#${fn}" >>${output}
if test ${SECONDSLEFT} -lt 7 # allow 7 seconds for initial compile time plus time to process next file
then
read --saveset
echo "You will need to reinvoke this script to complete. You have finished" `read --status` "files out of" `read --linecount`
exit
fi
done
echo "COMPLETED! Please find your output in ${output}."
read --clearset # Make sure it's all cleared out for the end
Compute a portion of a pagename (A "base" name)
A simple solution, suitable for just displaying the name:
{(sed 's/-Issue-.*$//' - {$Name})}
If you wanted to set a PV to that value you could do it like this:
{earlymx(set -s --pv BASENAME = (sed 's/-Issue-.*$//' - {$Name}))}
the basename is {$BASENAME}
(By using the Do a global search and replace on a large number of files
read --restoreset # this will not cause an error if there is nothing to restore
if test -z `read --status`
then
echo "Generating list of files to work off of..."
ls | grep -v RecentChanges >Tmp
fi
while read fn <Tmp
do
if test ${SECONDSLEFT} -lt 7 # allow 7 seconds for initial compile time plus time to process next file
then
read --prev --saveset # prev because main looping read has already gone to next line - must retrace steps
echo "You will need to reinvoke this script to complete. You have finished" `read --status` "files out of" `read --linecount`
exit
fi
#echo "Processing page ${fn}"
sed -vi 's/Pete /Peter /g' ${fn}
done
echo "COMPLETED!"
read --clearset
Make a group into a WikiTrail
ls MyGroup.* | grep -v 'RecentChanges|AnotherPageToSkip' | while read fn
do
echo "${fn}"
echo "<<|[[TrailIndexPage]]|>>" >${fn}<_TOP
echo "* [[${fn}]]" >>MyGroup.TrailIndexPage
done
Create a list of changes made by a particular author:
If you are searching for "John Smith" specifically
If you want to put it generically in a Profiles.GroupFooter (this allows for an optional space before each capital letter):
If you want to make the output look nicer and in a different order and etc (courtesy of Hans):||
||'''recent edits by Hans''' || ||
{(wikish grep -F "[[~Hans]]" Site.AllRecentChanges | sed 's/\* (.*?)\. \. \.\s*(.*?)\s*by(.*?)$/||$1 ||$2 ||/U' | sort -ur)}
Get a list of groups
Option 1 (quick - may miss a group every once in a while if it doesn't have a RecentChanges page)
Option 2 (takes longer but is complete)
Option 3 (with a later version of WikiSh)
Print off a different message if a pagelist returns no pages:
{(wikish set -s list = (pagelist group=XYZ wrap=inline fmt=#bygroup); if test -z "${list}"; then; echo "No pages found!";
else; echo "${list}"; fi)}
Rename a page fixing all links to it
set -s OldGroup = TestA
set -s OldPage = A
set -s NewGroup = TestB
set -s NewPage = B
sed -i 's|${OldGroup}([./]\)?)${OldPage}|${NewGroup}$1${NewPage}|gi' `pagelist link=${OldGroup}.${OldPage} sep=\n`
mv ${OldGroup}.${OldPage} ${NewGroup}.${NewPage}
Rename an entire group fixing all links to each page
read --clearset
#null --timeout:120
read --restoreset # this will not cause an error if there is nothing to restore
set -s OldGroup = TestA
set -s NewGroup = TestB
if test -z `read --status`
then
echo "Generating list of files to work off of..."
ls ${OldGroup}.* >Tmp
fi
while read fn <Tmp
do
if test ${SECONDSLEFT} -lt 15 # allow 15 seconds for initial compile time plus time to process next page
then
read --prev --saveset # prev because main looping read has already gone to next line - must retrace steps
echo "You will need to reinvoke this script to complete. You have finished" `read --status` "files out of" `read --linecount`
exit
fi
set -s OldPage = ${fn#*.} # calculate just the page part, losing the group
set -s NewPage = ${OldPage}
echo "Updating links ${OldGroup}.${OldPage} to ${NewGroup}.${NewPage} ..."
sed -vi 's|${OldGroup}([./]\)?)${OldPage}|${NewGroup}$1${NewPage}|gi' `pagelist link=${OldGroup}.${OldPage} sep=\n`
mv ${OldGroup}.${OldPage} ${NewGroup}.${NewPage}
echo "Moved page ${OldGroup}.${OldPage} to ${NewGroup}.${NewPage} ... DONE"
done
read --clearset
rm Tmp
echo "Entire Process COMPLETED!"
Populate a new group (created via a form) with a set of template pages
Create your templates in some (presumably protected) group. Let's say WikiMaster.Page1 and WikiMaster.Page2. Then on WikiMaster.Admin you would put this markup: ===(snip WikiMaster.Admin)=== {(wikish_form QUICKFORM PROCESS)}
New Group:
(:input text name=GroupName:)\\
(:input submit name=submit value=Create:)
(:input end:)
{(wikish source {$FullName}#validate)}
(:if false:)
[[#validate]]
if test -n "${submit}"
then
if ! test -n "${GroupName}"
then
echo "ERROR: Must specify the new group name."
else
if test -f ${GroupName}.Page1 || test -f ${GroupName}.Page2
then
echo "ERROR: ${GroupName} already exists."
else
echo "Creating New Team Page...\\\n\\\n"
cp WikiMaster.Page1 WikiMaster.Page2 ${GroupName}
echo "\\\n\\\n...DONE!"
fi
fi
fi
[[#validateend]]
(:if:)
===(snip)=== If you are going to let other people create the groups then you might want to do some other validations on the group name (no disallowed characters, etc), but this will get you the basic operation and you can fine-tune it from there. Splitting up (:pagelist:) output into separate pages, and creating a pagelist trailThis is useful if you are using a This recipe requires the following elements:
The following is an example of what is output: http://mySite.com/Group/Name displays:
* AccessKeys
* Audiences
* AuthUser
* AvailableActions
* BackupAndRestore
* BasicEditing
* BasicVariables
* Blocklist
* Categories
* ChangeLog
* ConditionalMarkup
* Contributors
* CreatingNewPages
* CustomInterMap
* CustomMarkup
displaying 1-15 of 93
. . . http://mySite.com/Group/Name?p=2 then displays:
* CustomWikiStyles
* DebugVariables
* DeletingPages
* DesignNotes
* DocumentationIndex
* EditVariables
* FAQ
* FilePermissions
* FmtPageName
* Functions
* Glossary
* GroupHeaders
* I18nVariables
* Images
* IncludeOtherPages
displaying 16-30 of 93
here's the WikiSh code:
/* CHECK FOR HTTPVAR - P=1 IF NONE PROVIDED */
{(wikish if test -n {$urlVarPageNum}; then; set pagenum = {$urlVarPageNum}; else; set pagenum = 1; fi; )}
/* SET GROUP, INTERVAL (LISTINGS PER PAGE) */
{(set -s groupname = "PmWiki")}
{(wikish set -s group = "group=${groupname}"; set -s name = "")}
{(set listingsperpage = 15)}
/* DETERMINE BEGINNING AND END VALUES OF PAGELIST'S COUNT=N..NN */
{(set pagenumOffset = ${pagenum}-1 )}
{(set nextPagenum = ${pagenum}+1 )}
{(set prevPagenum = ${pagenum}-1 )}
{(set start = ${pagenumOffset}*${listingsperpage}+1 )}
{(set end = ${start}+${listingsperpage}-1 )}
{(wikish set pagecount = `pagelist ${group} ${name} list=normal fmt=count` )}
/* CALL PAGELIST & BEGIN OUTPUT */
pages in {(echo ${groupname})}:
(:pagelist {(echo ${group})} {(echo ${name})} fmt=#simplename list=normal order=name count={(echo "${start}..${end}")} :)
/* COUNT HOW MANY PAGES YOU'LL NEED TO DISPLAY ALL ENTRIES */
{(wikish set numdisplaypages = 1; set testVal = ${numdisplaypages} * ${listingsperpage}; <<NOBREAK>>
while test ${testVal} -lt ${pagecount}; do; set numdisplaypages ++; <<NOBREAK>>
set testVal = ${numdisplaypages} * ${listingsperpage}; done; )}
/* DETERMINE LINKS */
/* NO SPACER IF ONLY 1 PAGE */
{(wikish set -s space = "|"; if test ${numdisplaypages} -eq 1; then; set -s space = ""; fi; )}
/* SET 'END' FOR "displaying nn-start to nn-end" */
{(wikish if test ${pagenum} -lt ${numdisplaypages}; then; set -s endN = ${end}; else; <<NOBREAK>>
set -s endN = ${pagecount}; fi; if test ${pagenum} -eq 1; then; if test ${numdisplaypages} -eq 1; <<NOBREAK>>
then set -s endN = ${pagecount}; fi; fi; )}
{(set -s tally = "displaying ${start}-${endN} of ${pagecount}")}
/* PREV & NEXT LINKS */
{(wikish if test ${pagenum} -eq 1; then; set -s prevLink = ""; else; set -s prevLink = <<NOBREAK>>
"[[{$PageUrl}?p=${prevPagenum} | << prev]] ${space} "; fi; )}
{(wikish if test ${pagenum} -eq ${numdisplaypages}; then; set -s nextLink = ""; else; <<NOBREAK>>
set -s nextLink = " ${space} [[{$PageUrl}?p=${nextPagenum} | next >>]]"; fi; )}
/* GENERATE PAGELIST TRAIL */
{(wikish set i = 1; set -s output = ""; set -s outputLink = ""; while test ${i} -le ${numdisplaypages}; do; <<NOBREAK>>
set -s outputLink = "[[{$PageUrl}?p=${i} | ${i}]]"; if test ${i} -eq ${pagenum}; then; <<NOBREAK>>
set -s outputLink = "'''${outputLink}'''"; fi; if test ${i} -eq 1; then; set -s output = "${outputLink}"; else; <<NOBREAK>>
set -s output = "${output} ${space} ${outputLink}"; fi; set i ++; done; <<NOBREAK>>
set -s output = "${prevLink}${output}${nextLink}"; )}
/* OUTPUT LINKS TO NEXT SET OF PAGES -- DON'T DISPLAY IF THERE'S ONLY ONE PAGE */
{(echo "${tally}")}
{(wikish if test ${numdisplaypages} -ne 1; then; echo "${output}"; fi; )}
overtones99 July 12, 2008, at 06:35 AM
# This function may be called with the following positional parameters:
# ${1} = a description of the pagelist ("pages in X")
# ${2} = a specified group (group=X)
# ${3} = a specified pagename (wildcard pattern) (name=X)
function PagelistPaginated
{
# SET GROUP, INTERVAL (LISTINGS PER PAGE)
set -s pagelistdesc = ${1} # positional parameter ("pages in X" label)
set -s groupname = ${2} # positional parameter (group=X)
set -s namename = ${3} # positional parameter (name=X)
if test -n ${groupname}
then
set -s group = "group=${groupname}"
else
set -s group = ""
fi
if test -n ${namename}
then
set -s name = "name=${namename}"
else
set -s name = ""
fi
set listingsperpage = 15
if test -n ${!p}
then
set pagenum = ${!p}
else
set pagenum = 1
fi
# DETERMINE BEGINNING AND END VALUES OF PAGELIST'S COUNT=N..NN
set pagenumOffset = ${pagenum}-1
set nextPagenum = ${pagenum}+1
set prevPagenum = ${pagenum}-1
set start = ${pagenumOffset}*${listingsperpage}+1
set end = ${start}+${listingsperpage}-1
set pagecount = `pagelist ${group} ${name} list=normal fmt=count`
# CALL PAGELIST & BEGIN OUTPUT
echo "pages in ${pagelistdesc}:"
pagelist wrap=inline ${group} ${name} fmt=#simplename list=normal order=name count=${start}..${end}
# COUNT HOW MANY PAGES YOU'LL NEED TO DISPLAY ALL ENTRIES
set numdisplaypages = 1
set testVal = ${numdisplaypages} * ${listingsperpage}
while test ${testVal} -lt ${pagecount}
do
set numdisplaypages ++
set testVal = ${numdisplaypages} * ${listingsperpage}
done
# DETERMINE LINKS
# NO SPACER IF ONLY 1 PAGE
set -s space = "|"
if test ${numdisplaypages} -eq 1
then
set -s space = ""
fi
# SET 'END' FOR "displaying nn-start to nn-end"
if test ${pagenum} -lt ${numdisplaypages}
then
set -s endN = ${end}
else
set -s endN = ${pagecount}
fi
if test ${pagenum} -eq 1 && test ${numdisplaypages} -eq 1
then
set -s endN = ${pagecount}
fi
set -s tally = "displaying ${start}-${endN} of ${pagecount}"
# PREV & NEXT LINKS
if test ${pagenum} -eq 1
then
set -s prevLink = ""
else
set -s prevLink = "[[{$FullName}?p=${prevPagenum} | << prev]] ${space} "
fi
if test ${pagenum} -eq ${numdisplaypages}
then
set -s nextLink = ""
else
set -s nextLink = " ${space} [[{$FullName}?p=${nextPagenum} | next >>]]"
fi
# GENERATE PAGELIST TRAIL
set i = 1
set -s output = ""
set -s outputLink = ""
while test ${i} -le ${numdisplaypages}
do
set -s outputLink = "[[{$FullName}?p=${i} | ${i}]]"
if test ${i} -eq ${pagenum}
then
set -s outputLink = "'''${outputLink}'''"
fi
if test ${i} -eq 1
then
set -s output = "${outputLink}"
else
set -s output = "${output} ${space} ${outputLink}"
fi
set i ++
done
set -s output = "${prevLink}${output}${nextLink}"
# OUTPUT LINKS TO NEXT SET OF PAGES -- DON'T DISPLAY IF THERE'S ONLY ONE PAGE
echo "\n${tally}"
if test ${numdisplaypages} -ne 1
then
echo "${output}"
fi
}
{(wikish PagelistPaginated "Description for top of pagelist" GroupX GroupY.PageWildcard*)}
Shorten titles of very long pages, and add ellipsesLong pagetitles on occasion mess up the formatting of tables you've created and make for harder reading/browsing, so this is a nice way to shorten the title if it's too long, and add an "..." to the end of it. I've found this especially useful on Category pages. Add the following pagelist template to your Site/LocalTemplates
----
/* USING WikiSh TO ADD ELLIPSES TO LONG TITLES */
!!!fmt=#shortentitles
[@
[[#shortentitles]]
(:template first:)
|| width=30%
(:template each:)
{(set -s pageName = "{=$Group}.{=$Name}")}
{(set -s titleName = "{=$Namespaced}")}
{(set -s elipsis = "...")}
{(set maxStringSize = 30)}
/* shorten title and add "..." if it's too long */
{(wikish if test ${#titleName} -gt ${maxStringSize}; then; set -s titleNamePost = <<NOBREAK>>
"${titleName:0:${maxStringSize}}${elipsis}"; else; set -s titleNamePost = "${titleName}"; fi; )}
||[[{=$Group}/{=$Name} | {(echo "${titleNamePost}")}]] ||[-([[{=$Group}(/Index)]], added {=$PageCreationDate})-] ||
[[#shortentitlesend]]
@ ]
then, Access Key... (PmWiki, added 11 Jan 2006) Audiences (PmWiki, added 31 Dec 1969) Auth User (PmWiki, added 31 Dec 1969) Available ... (PmWiki, added 31 Dec 1969) Backup And... (PmWiki, added 15 Dec 2005) Basic Edit... (PmWiki, added 31 Dec 1969) Basic Vari... (PmWiki, added 31 Dec 1969) Blocklist (PmWiki, added 29 Sep 2006) Categories (PmWiki, added 31 Dec 1969) Change Log (PmWiki, added 31 Dec 1969) overtones99 July 12, 2008, at 08:29 AM . . . |