|
Cookbook /
WikiSh Examples and ApplicationsThis page gives examples or mini-applications of WikiSh in action... Note that examples surrounded by 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!"
Create a set of template pages which you then copy into a new group specified in a form
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 . . . |