You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jspwiki.apache.org by Christophe Dupriez <ch...@destin.be> on 2008/02/15 09:10:32 UTC

Aliasing long Wiki markup

Hi Again!

When users are putting often the same long markup sequences, it may be 
useful to define "aliases".

Attached modifications allows to:

1) define aliases in jspwiki.properties. For instance:
   #Applications shortcuts
   alias.citedby=[{ReferringPagesPlugin title='!Cited by:%n' 
exclude='Main,LeftMenu'}]

2) Call those alliases in pages: the syntax is the same than for 
variable inclusion but a "$" sign is added at the end.
   For instance: [{$citedby$}]
   The WikiMarkup inside the alias is interpreted.

The nice thing is also that you can change the definition of an Alias 
without changing the wiki pages...

Final note: \n is allowed in jspwiki.properties to indicate a end of 
line (\n\n for end of paragraph)

Attached source code is for 2.6.1. VariableContent.java is in the 
"parser" directory.

Have a nice day!

Christophe

Re: Aliasing long Wiki markup

Posted by Janne Jalkanen <Ja...@ecyrd.com>.
> Macros: this is more a "micro" than a macro: [{$xxxx$}] is simply  
> replaced by a string coming from the jspwiki.properties file (no  
> danger of infection there!).
> The expansion is parsed for Wiki markup.

Whatever they are, they're not variables and should not be treated as  
such.  The semantics and the intent are completely different.  This  
is, as far as I am concerned, a kludge, and I would not be willing to  
take it in.  It needs more design, way more design than this.

Expanding the WikiMarkup should be done by either extending the  
JSPWikiMarkupParser or adding new PageFilters.

> If you have better ideas, I will buy them: I need such a mechanism  
> because http://www.destin.be/CAFE  contains more than 10 thousand  
> pages coming from a database: generating plugin calls without  
> anyway to correct/adapt them globally is foolish.

As I said, develop a PageFilter to take care of this instead of a  
hack in the VariableManager, that way others can use it too.

/Janne

Re: Aliasing long Wiki markup

Posted by Janne Jalkanen <Ja...@ecyrd.com>.
I would recommend that you implement a PageFilter which implements  
this for you.

/Janne

On 15 Feb 2008, at 21:15, Christophe Dupriez wrote:

> Hi Janne,
>
> Macros: this is more a "micro" than a macro: [{$xxxx$}] is simply  
> replaced by a string coming from the jspwiki.properties file (no  
> danger of infection there!).
> The expansion is parsed for Wiki markup.
>
> A can of worms? No parameters, no programmability for the end user.
>
> Eventualy, one could want to go further: disallow plugins except if  
> called by this mechanism... Which could close a can of  
> programmability that users may not always need.
>
> If you have better ideas, I will buy them: I need such a mechanism  
> because http://www.destin.be/CAFE  contains more than 10 thousand  
> pages coming from a database: generating plugin calls without  
> anyway to correct/adapt them globally is foolish.
>
> Christophe
>
> Janne Jalkanen a écrit :
>>
>> Again, JIRA and patches.
>>
>> But frankly, I would really hesitate to add something like this.   
>> It opens up a can of worms.  Macros can make life very  
>> complicated, so this needs a lot more design than this.
>>
>> /Janne
>>
>> On Feb 15, 2008, at 10:10 , Christophe Dupriez wrote:
>>
>>> Hi Again!
>>>
>>> When users are putting often the same long markup sequences, it  
>>> may be useful to define "aliases".
>>>
>>> Attached modifications allows to:
>>>
>>> 1) define aliases in jspwiki.properties. For instance:
>>>   #Applications shortcuts
>>>   alias.citedby=[{ReferringPagesPlugin title='!Cited by:%n'  
>>> exclude='Main,LeftMenu'}]
>>>
>>> 2) Call those alliases in pages: the syntax is the same than for  
>>> variable inclusion but a "$" sign is added at the end.
>>>   For instance: [{$citedby$}]
>>>   The WikiMarkup inside the alias is interpreted.
>>>
>>> The nice thing is also that you can change the definition of an  
>>> Alias without changing the wiki pages...
>>>
>>> Final note: \n is allowed in jspwiki.properties to indicate a end  
>>> of line (\n\n for end of paragraph)
>>>
>>> Attached source code is for 2.6.1. VariableContent.java is in the  
>>> "parser" directory.
>>>
>>> Have a nice day!
>>>
>>> Christophe
>>> /*
>>>     JSPWiki - a JSP-based WikiWiki clone.
>>>
>>>     Copyright (C) 2001 Janne Jalkanen (Janne.Jalkanen@iki.fi)
>>>
>>>     This program is free software; you can redistribute it and/or  
>>> modify
>>>     it under the terms of the GNU Lesser General Public License  
>>> as published by
>>>     the Free Software Foundation; either version 2.1 of the  
>>> License, or
>>>     (at your option) any later version.
>>>
>>>     This program is distributed in the hope that it will be useful,
>>>     but WITHOUT ANY WARRANTY; without even the implied warranty of
>>>     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>>     GNU Lesser General Public License for more details.
>>>
>>>     You should have received a copy of the GNU Lesser General  
>>> Public License
>>>     along with this program; if not, write to the Free Software
>>>     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA   
>>> 02111-1307  USA
>>>  */
>>> package com.ecyrd.jspwiki;
>>>
>>> import java.security.Principal;
>>> import java.util.Date;
>>> import java.util.Iterator;
>>> import java.util.List;
>>> import java.util.Properties;
>>> import java.io.IOException;
>>>
>>> import javax.servlet.http.HttpServletRequest;
>>> import javax.servlet.http.HttpSession;
>>>
>>> import com.ecyrd.jspwiki.filters.PageFilter;
>>> import com.ecyrd.jspwiki.modules.InternalModule;
>>>
>>> import com.ecyrd.jspwiki.render.RenderingManager;
>>> import com.ecyrd.jspwiki.parser.MarkupParser;
>>> import com.ecyrd.jspwiki.parser.WikiDocument;
>>>
>>> /**
>>>  *  Manages variables.  Variables are case-insensitive.  A list  
>>> of all
>>>  *  available variables is on a Wiki page called "WikiVariables".
>>>  *
>>>  *  @author Janne Jalkanen
>>>  *  @since 1.9.20.
>>>  */
>>> public class VariableManager
>>> {
>>>     //private static Logger log = Logger.getLogger 
>>> ( VariableManager.class );
>>>
>>>     // FIXME: These are probably obsolete.
>>>     public static final String VAR_ERROR = "error";
>>>     public static final String VAR_MSG   = "msg";
>>>
>>>     /**
>>>      *  Contains a list of those properties that shall never be  
>>> shown.
>>>      *  Put names here in lower case.
>>>      */
>>>
>>>     static final String[] THE_BIG_NO_NO_LIST = {
>>>         "jspwiki.auth.masterpassword"
>>>     };
>>>
>>>     /**
>>>      *  Creates a VariableManager object using the property list  
>>> given.
>>>      *  @param props The properties.
>>>      */
>>>     public VariableManager( Properties props )
>>>     {
>>>     }
>>>
>>>     /**
>>>      *  Returns true if the link is really command to insert
>>>      *  a variable.
>>>      *  <P>
>>>      *  Currently we just check if the link starts with "{$".
>>>      *
>>>      *  @param link The link text
>>>      *  @return true, if this represents a variable link.
>>>      */
>>>     public static boolean isVariableLink( String link )
>>>     {
>>>         return link.startsWith("{$");
>>>     }
>>>
>>>     /**
>>>      *  Parses the link and finds a value.  This is essentially used
>>>      *  once {@link #isVariableLink(String)} has found that the  
>>> link text
>>>      *  actually contains a variable.  For example, you could  
>>> pass in
>>>      *  "{$username}" and get back "JanneJalkanen".
>>>      *
>>>      *  @param  context The WikiContext
>>>      *  @param  link    The link text containing the variable name.
>>>      *  @return The variable value.
>>>      *  @throws IllegalArgumentException If the format is not  
>>> valid (does not
>>>      *          start with "{$", is zero length, etc.)
>>>      *  @throws NoSuchVariableException If a variable is not known.
>>>      */
>>>     public String parseAndGetValue( WikiContext context,
>>>                                     String link )
>>>         throws IllegalArgumentException,
>>>                IOException,
>>>                NoSuchVariableException
>>>     {
>>>         if( !link.startsWith("{$") )
>>>             throw new IllegalArgumentException( "Link does not  
>>> start with {$" );
>>>
>>>         if( !link.endsWith("}") )
>>>             throw new IllegalArgumentException( "Link does not  
>>> end with }" );
>>>
>>>         String varName = link.substring(2,link.length()-1);
>>>
>>>         return getValue( context, varName.trim() );
>>>     }
>>>
>>>     /**
>>>      *  This method does in-place expansion of any variables.   
>>> However,
>>>      *  the expansion is not done twice, that is, a variable  
>>> containing text $variable
>>>      *  will not be expanded.
>>>      *  <P>
>>>      *  The variables should be in the same format  
>>> ({$variablename} as in the web
>>>      *  pages.
>>>      *
>>>      *  @param context The WikiContext of the current page.
>>>      *  @param source  The source string.
>>>      *  @return The source string with variables expanded.
>>>      */
>>>     // FIXME: somewhat slow.
>>>     public String expandVariables( WikiContext context,
>>>                                    String      source )
>>>     {
>>>         StringBuffer result = new StringBuffer();
>>>
>>>         for( int i = 0; i < source.length(); i++ )
>>>         {
>>>             if( source.charAt(i) == '{' )
>>>             {
>>>                 if( i < source.length()-2 && source.charAt(i+1)  
>>> == '$' )
>>>                 {
>>>                     int end = source.indexOf( '}', i );
>>>
>>>                     if( end != -1 )
>>>                     {
>>>                         String varname = source.substring( i+2,  
>>> end );
>>>                         String value;
>>>
>>>                         try
>>>                         {
>>>                             value = getValue( context, varname );
>>>                         }
>>>                         catch( IOException e )
>>>                         {
>>>                             value = e.getMessage();
>>>                         }
>>>                         catch( NoSuchVariableException e )
>>>                         {
>>>                             value = e.getMessage();
>>>                         }
>>>                         catch( IllegalArgumentException e )
>>>                         {
>>>                             value = e.getMessage();
>>>                         }
>>>
>>>                         result.append( value );
>>>                         i = end;
>>>                         continue;
>>>                     }
>>>                 }
>>>                 else
>>>                 {
>>>                     result.append( '{' );
>>>                 }
>>>             }
>>>             else
>>>             {
>>>                 result.append( source.charAt(i) );
>>>             }
>>>         }
>>>
>>>         return result.toString();
>>>     }
>>>
>>>     // Probably this should be a method of WikiContext...
>>>     private String makeHTML (WikiContext context, String  
>>> wikitext) throws IOException
>>>     {
>>>         String result = "";
>>>
>>>         RenderingManager mgr = context.getEngine 
>>> ().getRenderingManager();
>>>         MarkupParser parser = mgr.getParser(context, wikitext);
>>>         WikiDocument doc = parser.parse();
>>>         result = mgr.getHTML( context, doc );
>>>         return result;
>>>     }
>>>
>>>     /**
>>>      *  Returns the value of a named variable.  See {@link  
>>> #getValue(WikiContext, String)}.
>>>      *  The only difference is that this method does not throw an  
>>> exception, but it
>>>      *  returns the given default value instead.
>>>      *
>>>      *  @param context WikiContext
>>>      *  @param varName The name of the variable
>>>      *  @param defValue A default value.
>>>      *  @return The variable value, or if not found, the default  
>>> value.
>>>      */
>>>     public String getValue( WikiContext context, String varName,  
>>> String defValue )
>>>     {
>>>         try
>>>         {
>>>             return getValue( context, varName );
>>>         }
>>>         catch( NoSuchVariableException e )
>>>         {
>>>             return defValue;
>>>         }
>>>         catch( IOException e )
>>>         {
>>>             return defValue;
>>>         }
>>>     }
>>>
>>>     /**
>>>      *  Returns a value of the named variable.  The resolving  
>>> order is
>>>      *  <ol>
>>>      *    <li>Known "constant" name, such as "pagename", etc.   
>>> This is so
>>>      *        that pages could not override certain constants.
>>>      *    <li>WikiContext local variable.  This allows a  
>>> programmer to
>>>      *        set a parameter which cannot be overridden by user.
>>>      *    <li>HTTP Session
>>>      *    <li>HTTP Request parameters
>>>      *    <li>WikiPage variable.  As set by the user with the SET  
>>> directive.
>>>      *    <li>jspwiki.properties
>>>      *  </ol>
>>>      *
>>>      *  Use this method only whenever you really need to have a  
>>> parameter that
>>>      *  can be overridden by anyone using the wiki.
>>>      *
>>>      *  @param context The WikiContext
>>>      *  @param varName Name of the variable.
>>>      *
>>>      *  @return The variable value.
>>>      *
>>>      *  @throws IllegalArgumentException If the name is somehow  
>>> broken.
>>>      *  @throws NoSuchVariableException If a variable is not known.
>>>      */
>>>     // FIXME: Currently a bit complicated.  Perhaps should use  
>>> reflection
>>>     //        or something to make an easy way of doing stuff.
>>>     public String getValue( WikiContext context,
>>>                             String      varName )
>>>         throws IllegalArgumentException,
>>>                IOException,
>>>                NoSuchVariableException
>>>     {
>>>         if( varName == null )
>>>             throw new IllegalArgumentException( "Null variable  
>>> name." );
>>>
>>>         if( varName.length() == 0 )
>>>             throw new IllegalArgumentException( "Zero length  
>>> variable name." );
>>>
>>>         // Faster than doing equalsIgnoreCase()
>>>         String name = varName.toLowerCase();
>>>
>>>         for( int i = 0; i < THE_BIG_NO_NO_LIST.length; i++ )
>>>         {
>>>             if( name.equals(THE_BIG_NO_NO_LIST[i]) )
>>>                 return ""; // FIXME: Should this be something  
>>> different?
>>>         }
>>>
>>>         if( name.equals("pagename") )
>>>         {
>>>             return context.getPage().getName();
>>>         }
>>>         else if( name.equals("applicationname") )
>>>         {
>>>             return context.getEngine().getApplicationName();
>>>         }
>>>         else if( name.equals("jspwikiversion") )
>>>         {
>>>             return Release.getVersionString();
>>>         }
>>>         else if( name.equals("encoding") )
>>>         {
>>>             return context.getEngine().getContentEncoding();
>>>         }
>>>         else if( name.equals("totalpages") )
>>>         {
>>>             return Integer.toString(context.getEngine 
>>> ().getPageCount());
>>>         }
>>>         else if( name.equals("pageprovider") )
>>>         {
>>>             return context.getEngine().getCurrentProvider();
>>>         }
>>>         else if( name.equals("pageproviderdescription") )
>>>         {
>>>             return context.getEngine().getCurrentProviderInfo();
>>>         }
>>>         else if( name.equals("attachmentprovider") )
>>>         {
>>>             WikiProvider p = context.getEngine 
>>> ().getAttachmentManager().getCurrentProvider();
>>>             return (p != null) ? p.getClass().getName() : "-";
>>>         }
>>>         else if( name.equals("attachmentproviderdescription") )
>>>         {
>>>             WikiProvider p = context.getEngine 
>>> ().getAttachmentManager().getCurrentProvider();
>>>
>>>             return (p != null) ? p.getProviderInfo() : "-";
>>>         }
>>>         else if( name.equals("interwikilinks") )
>>>         {
>>>             StringBuffer res = new StringBuffer();
>>>
>>>             for( Iterator i = context.getEngine 
>>> ().getAllInterWikiLinks().iterator(); i.hasNext(); )
>>>             {
>>>                 if( res.length() > 0 ) res.append(", ");
>>>                 String link = (String) i.next();
>>>                 res.append( link );
>>>                 res.append( " --> " );
>>>                 res.append( context.getEngine().getInterWikiURL 
>>> (link) );
>>>             }
>>>             return res.toString();
>>>         }
>>>         else if( name.equals("inlinedimages") )
>>>         {
>>>             StringBuffer res = new StringBuffer();
>>>
>>>             for( Iterator i = context.getEngine 
>>> ().getAllInlinedImagePatterns().iterator(); i.hasNext(); )
>>>             {
>>>                 if( res.length() > 0 ) res.append(", ");
>>>
>>>                 String ptrn = (String) i.next();
>>>                 res.append(ptrn);
>>>             }
>>>
>>>             return res.toString();
>>>         }
>>>         else if( name.equals("pluginpath") )
>>>         {
>>>             String s = context.getEngine().getPluginSearchPath();
>>>
>>>             return (s == null) ? "-" : s;
>>>         }
>>>         else if( name.equals("baseurl") )
>>>         {
>>>             return context.getEngine().getBaseURL();
>>>         }
>>>         else if( name.equals("uptime") )
>>>         {
>>>             Date now = new Date();
>>>             long secondsRunning = (now.getTime() -  
>>> context.getEngine().getStartTime().getTime())/1000L;
>>>
>>>             long seconds = secondsRunning % 60;
>>>             long minutes = (secondsRunning /= 60) % 60;
>>>             long hours   = (secondsRunning /= 60) % 24;
>>>             long days    = secondsRunning /= 24;
>>>
>>>             return days+"d, "+hours+"h "+minutes+"m "+seconds+"s";
>>>         }
>>>         else if( name.equals("loginstatus") )
>>>         {
>>>             WikiSession session = context.getWikiSession();
>>>             return session.getStatus();
>>>         }
>>>         else if( name.equals("username") )
>>>         {
>>>             Principal wup = context.getCurrentUser();
>>>
>>>             return wup != null ? wup.getName() : "not logged in";
>>>         }
>>>         else if( name.equals("requestcontext") )
>>>         {
>>>             return context.getRequestContext();
>>>         }
>>>         else if( name.equals("pagefilters") )
>>>         {
>>>             List filters = context.getEngine().getFilterManager 
>>> ().getFilterList();
>>>             StringBuffer sb = new StringBuffer();
>>>
>>>             for( Iterator i = filters.iterator(); i.hasNext(); )
>>>             {
>>>                 PageFilter pf = (PageFilter)i.next();
>>>                 String f = pf.getClass().getName();
>>>
>>>                 if( pf instanceof InternalModule )
>>>                     continue;
>>>
>>>                 if( sb.length() > 0 ) sb.append(", ");
>>>                 sb.append( f );
>>>             }
>>>
>>>             return sb.toString();
>>>         }
>>>         else
>>>         {
>>>             //
>>>             // Check if such a context variable exists,
>>>             // returning its string representation.
>>>             //
>>>             if( (context.getVariable( varName )) != null )
>>>             {
>>>                 return context.getVariable( varName ).toString();
>>>             }
>>>
>>>             //
>>>             //  Well, I guess it wasn't a final straw.  We also  
>>> allow
>>>             //  variables from the session and the request (in  
>>> this order).
>>>             //
>>>
>>>             HttpServletRequest req = context.getHttpRequest();
>>>             if( req != null && req.getSession() != null )
>>>             {
>>>                 HttpSession session = req.getSession();
>>>
>>>                 try
>>>                 {
>>>                     String s;
>>>
>>>                     if( (s = (String)session.getAttribute 
>>> ( varName )) != null )
>>>                         return s;
>>>
>>>                     if( (s = context.getHttpParameter 
>>> ( varName )) != null )
>>>                         return s;
>>>                 }
>>>                 catch( ClassCastException e ) {}
>>>             }
>>>
>>>             // And the final straw: see if the current page has  
>>> named metadata.
>>>
>>>             WikiPage pg = context.getPage();
>>>             if( pg != null )
>>>             {
>>>                 Object metadata = pg.getAttribute( varName );
>>>                 if( metadata != null )
>>>                     return metadata.toString();
>>>             }
>>>
>>>             // And the final straw part 2: see if the "real"  
>>> current page has
>>>             // named metadata. This allows a parent page to  
>>> control a inserted
>>>             // page through defining variables
>>>             WikiPage rpg = context.getRealPage();
>>>             if( rpg != null )
>>>             {
>>>                 Object metadata = rpg.getAttribute( varName );
>>>                 if( metadata != null )
>>>                     return metadata.toString();
>>>             }
>>>
>>>             // Next-to-final straw: attempt to fetch using  
>>> property name
>>>             // We don't allow fetching any other properties than  
>>> those starting
>>>             // with "jspwiki.".  I know my own code, but I can't  
>>> vouch for bugs
>>>             // in other people's code... :-)
>>>
>>>             Properties props = context.getEngine 
>>> ().getWikiProperties();
>>>             if( varName.startsWith("jspwiki.") )
>>>             {
>>>
>>>                 String s = props.getProperty( varName );
>>>                 if( s != null )
>>>                 {
>>>                     return s;
>>>                 }
>>>             }
>>>             // Our local preference: be able to define Aliases in  
>>> properties to simplify long and repeated plugins!
>>>             else if ((varName.length() > 1) && (varName.charAt 
>>> (varName.length()-1) == '$')) {
>>>                 String s = props.getProperty 
>>> ( "alias."+varName.substring( 0, varName.length()-1 ));
>>>                 if( s != null )
>>>                 {
>>>                     return makeHTML( context, s );
>>>                 }
>>>                throw new NoSuchVariableException( "No alias  
>>> "+varName.substring( 0, varName.length()-1 )+" defined in JSPWiki  
>>> properties." );
>>>             }
>>>
>>>             //
>>>             //  Final defaults for some known quantities.
>>>             //
>>>
>>>             if( varName.equals( VAR_ERROR ) || varName.equals 
>>> ( VAR_MSG ) )
>>>                 return "";
>>>
>>>             throw new NoSuchVariableException( "No variable  
>>> "+varName+" defined." );
>>>         }
>>>     }
>>>
>>> }
>>
>>
>>
>>
>


Re: Aliasing long Wiki markup

Posted by Christophe Dupriez <ch...@destin.be>.
Hi Janne,

Macros: this is more a "micro" than a macro: [{$xxxx$}] is simply 
replaced by a string coming from the jspwiki.properties file (no danger 
of infection there!).
The expansion is parsed for Wiki markup.

A can of worms? No parameters, no programmability for the end user.

Eventualy, one could want to go further: disallow plugins except if 
called by this mechanism... Which could close a can of programmability 
that users may not always need.

If you have better ideas, I will buy them: I need such a mechanism 
because http://www.destin.be/CAFE  contains more than 10 thousand pages 
coming from a database: generating plugin calls without anyway to 
correct/adapt them globally is foolish.

Christophe

Janne Jalkanen a écrit :
>
> Again, JIRA and patches.
>
> But frankly, I would really hesitate to add something like this.  It 
> opens up a can of worms.  Macros can make life very complicated, so 
> this needs a lot more design than this.
>
> /Janne
>
> On Feb 15, 2008, at 10:10 , Christophe Dupriez wrote:
>
>> Hi Again!
>>
>> When users are putting often the same long markup sequences, it may 
>> be useful to define "aliases".
>>
>> Attached modifications allows to:
>>
>> 1) define aliases in jspwiki.properties. For instance:
>>   #Applications shortcuts
>>   alias.citedby=[{ReferringPagesPlugin title='!Cited by:%n' 
>> exclude='Main,LeftMenu'}]
>>
>> 2) Call those alliases in pages: the syntax is the same than for 
>> variable inclusion but a "$" sign is added at the end.
>>   For instance: [{$citedby$}]
>>   The WikiMarkup inside the alias is interpreted.
>>
>> The nice thing is also that you can change the definition of an Alias 
>> without changing the wiki pages...
>>
>> Final note: \n is allowed in jspwiki.properties to indicate a end of 
>> line (\n\n for end of paragraph)
>>
>> Attached source code is for 2.6.1. VariableContent.java is in the 
>> "parser" directory.
>>
>> Have a nice day!
>>
>> Christophe
>> /*
>>     JSPWiki - a JSP-based WikiWiki clone.
>>
>>     Copyright (C) 2001 Janne Jalkanen (Janne.Jalkanen@iki.fi)
>>
>>     This program is free software; you can redistribute it and/or modify
>>     it under the terms of the GNU Lesser General Public License as 
>> published by
>>     the Free Software Foundation; either version 2.1 of the License, or
>>     (at your option) any later version.
>>
>>     This program is distributed in the hope that it will be useful,
>>     but WITHOUT ANY WARRANTY; without even the implied warranty of
>>     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>     GNU Lesser General Public License for more details.
>>
>>     You should have received a copy of the GNU Lesser General Public 
>> License
>>     along with this program; if not, write to the Free Software
>>     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  
>> 02111-1307  USA
>>  */
>> package com.ecyrd.jspwiki;
>>
>> import java.security.Principal;
>> import java.util.Date;
>> import java.util.Iterator;
>> import java.util.List;
>> import java.util.Properties;
>> import java.io.IOException;
>>
>> import javax.servlet.http.HttpServletRequest;
>> import javax.servlet.http.HttpSession;
>>
>> import com.ecyrd.jspwiki.filters.PageFilter;
>> import com.ecyrd.jspwiki.modules.InternalModule;
>>
>> import com.ecyrd.jspwiki.render.RenderingManager;
>> import com.ecyrd.jspwiki.parser.MarkupParser;
>> import com.ecyrd.jspwiki.parser.WikiDocument;
>>
>> /**
>>  *  Manages variables.  Variables are case-insensitive.  A list of all
>>  *  available variables is on a Wiki page called "WikiVariables".
>>  *
>>  *  @author Janne Jalkanen
>>  *  @since 1.9.20.
>>  */
>> public class VariableManager
>> {
>>     //private static Logger log = Logger.getLogger( 
>> VariableManager.class );
>>
>>     // FIXME: These are probably obsolete.
>>     public static final String VAR_ERROR = "error";
>>     public static final String VAR_MSG   = "msg";
>>
>>     /**
>>      *  Contains a list of those properties that shall never be shown.
>>      *  Put names here in lower case.
>>      */
>>
>>     static final String[] THE_BIG_NO_NO_LIST = {
>>         "jspwiki.auth.masterpassword"
>>     };
>>
>>     /**
>>      *  Creates a VariableManager object using the property list given.
>>      *  @param props The properties.
>>      */
>>     public VariableManager( Properties props )
>>     {
>>     }
>>
>>     /**
>>      *  Returns true if the link is really command to insert
>>      *  a variable.
>>      *  <P>
>>      *  Currently we just check if the link starts with "{$".
>>      *
>>      *  @param link The link text
>>      *  @return true, if this represents a variable link.
>>      */
>>     public static boolean isVariableLink( String link )
>>     {
>>         return link.startsWith("{$");
>>     }
>>
>>     /**
>>      *  Parses the link and finds a value.  This is essentially used
>>      *  once {@link #isVariableLink(String)} has found that the link 
>> text
>>      *  actually contains a variable.  For example, you could pass in
>>      *  "{$username}" and get back "JanneJalkanen".
>>      *
>>      *  @param  context The WikiContext
>>      *  @param  link    The link text containing the variable name.
>>      *  @return The variable value.
>>      *  @throws IllegalArgumentException If the format is not valid 
>> (does not
>>      *          start with "{$", is zero length, etc.)
>>      *  @throws NoSuchVariableException If a variable is not known.
>>      */
>>     public String parseAndGetValue( WikiContext context,
>>                                     String link )
>>         throws IllegalArgumentException,
>>                IOException,
>>                NoSuchVariableException
>>     {
>>         if( !link.startsWith("{$") )
>>             throw new IllegalArgumentException( "Link does not start 
>> with {$" );
>>
>>         if( !link.endsWith("}") )
>>             throw new IllegalArgumentException( "Link does not end 
>> with }" );
>>
>>         String varName = link.substring(2,link.length()-1);
>>
>>         return getValue( context, varName.trim() );
>>     }
>>
>>     /**
>>      *  This method does in-place expansion of any variables.  However,
>>      *  the expansion is not done twice, that is, a variable 
>> containing text $variable
>>      *  will not be expanded.
>>      *  <P>
>>      *  The variables should be in the same format ({$variablename} 
>> as in the web
>>      *  pages.
>>      *
>>      *  @param context The WikiContext of the current page.
>>      *  @param source  The source string.
>>      *  @return The source string with variables expanded.
>>      */
>>     // FIXME: somewhat slow.
>>     public String expandVariables( WikiContext context,
>>                                    String      source )
>>     {
>>         StringBuffer result = new StringBuffer();
>>
>>         for( int i = 0; i < source.length(); i++ )
>>         {
>>             if( source.charAt(i) == '{' )
>>             {
>>                 if( i < source.length()-2 && source.charAt(i+1) == '$' )
>>                 {
>>                     int end = source.indexOf( '}', i );
>>
>>                     if( end != -1 )
>>                     {
>>                         String varname = source.substring( i+2, end );
>>                         String value;
>>
>>                         try
>>                         {
>>                             value = getValue( context, varname );
>>                         }
>>                         catch( IOException e )
>>                         {
>>                             value = e.getMessage();
>>                         }
>>                         catch( NoSuchVariableException e )
>>                         {
>>                             value = e.getMessage();
>>                         }
>>                         catch( IllegalArgumentException e )
>>                         {
>>                             value = e.getMessage();
>>                         }
>>
>>                         result.append( value );
>>                         i = end;
>>                         continue;
>>                     }
>>                 }
>>                 else
>>                 {
>>                     result.append( '{' );
>>                 }
>>             }
>>             else
>>             {
>>                 result.append( source.charAt(i) );
>>             }
>>         }
>>
>>         return result.toString();
>>     }
>>
>>     // Probably this should be a method of WikiContext...
>>     private String makeHTML (WikiContext context, String wikitext) 
>> throws IOException
>>     {
>>         String result = "";
>>
>>         RenderingManager mgr = 
>> context.getEngine().getRenderingManager();
>>         MarkupParser parser = mgr.getParser(context, wikitext);
>>         WikiDocument doc = parser.parse();
>>         result = mgr.getHTML( context, doc );
>>         return result;
>>     }
>>
>>     /**
>>      *  Returns the value of a named variable.  See {@link 
>> #getValue(WikiContext, String)}.
>>      *  The only difference is that this method does not throw an 
>> exception, but it
>>      *  returns the given default value instead.
>>      *
>>      *  @param context WikiContext
>>      *  @param varName The name of the variable
>>      *  @param defValue A default value.
>>      *  @return The variable value, or if not found, the default value.
>>      */
>>     public String getValue( WikiContext context, String varName, 
>> String defValue )
>>     {
>>         try
>>         {
>>             return getValue( context, varName );
>>         }
>>         catch( NoSuchVariableException e )
>>         {
>>             return defValue;
>>         }
>>         catch( IOException e )
>>         {
>>             return defValue;
>>         }
>>     }
>>
>>     /**
>>      *  Returns a value of the named variable.  The resolving order is
>>      *  <ol>
>>      *    <li>Known "constant" name, such as "pagename", etc.  This 
>> is so
>>      *        that pages could not override certain constants.
>>      *    <li>WikiContext local variable.  This allows a programmer to
>>      *        set a parameter which cannot be overridden by user.
>>      *    <li>HTTP Session
>>      *    <li>HTTP Request parameters
>>      *    <li>WikiPage variable.  As set by the user with the SET 
>> directive.
>>      *    <li>jspwiki.properties
>>      *  </ol>
>>      *
>>      *  Use this method only whenever you really need to have a 
>> parameter that
>>      *  can be overridden by anyone using the wiki.
>>      *
>>      *  @param context The WikiContext
>>      *  @param varName Name of the variable.
>>      *
>>      *  @return The variable value.
>>      *
>>      *  @throws IllegalArgumentException If the name is somehow broken.
>>      *  @throws NoSuchVariableException If a variable is not known.
>>      */
>>     // FIXME: Currently a bit complicated.  Perhaps should use 
>> reflection
>>     //        or something to make an easy way of doing stuff.
>>     public String getValue( WikiContext context,
>>                             String      varName )
>>         throws IllegalArgumentException,
>>                IOException,
>>                NoSuchVariableException
>>     {
>>         if( varName == null )
>>             throw new IllegalArgumentException( "Null variable name." );
>>
>>         if( varName.length() == 0 )
>>             throw new IllegalArgumentException( "Zero length variable 
>> name." );
>>
>>         // Faster than doing equalsIgnoreCase()
>>         String name = varName.toLowerCase();
>>
>>         for( int i = 0; i < THE_BIG_NO_NO_LIST.length; i++ )
>>         {
>>             if( name.equals(THE_BIG_NO_NO_LIST[i]) )
>>                 return ""; // FIXME: Should this be something different?
>>         }
>>
>>         if( name.equals("pagename") )
>>         {
>>             return context.getPage().getName();
>>         }
>>         else if( name.equals("applicationname") )
>>         {
>>             return context.getEngine().getApplicationName();
>>         }
>>         else if( name.equals("jspwikiversion") )
>>         {
>>             return Release.getVersionString();
>>         }
>>         else if( name.equals("encoding") )
>>         {
>>             return context.getEngine().getContentEncoding();
>>         }
>>         else if( name.equals("totalpages") )
>>         {
>>             return Integer.toString(context.getEngine().getPageCount());
>>         }
>>         else if( name.equals("pageprovider") )
>>         {
>>             return context.getEngine().getCurrentProvider();
>>         }
>>         else if( name.equals("pageproviderdescription") )
>>         {
>>             return context.getEngine().getCurrentProviderInfo();
>>         }
>>         else if( name.equals("attachmentprovider") )
>>         {
>>             WikiProvider p = 
>> context.getEngine().getAttachmentManager().getCurrentProvider();
>>             return (p != null) ? p.getClass().getName() : "-";
>>         }
>>         else if( name.equals("attachmentproviderdescription") )
>>         {
>>             WikiProvider p = 
>> context.getEngine().getAttachmentManager().getCurrentProvider();
>>
>>             return (p != null) ? p.getProviderInfo() : "-";
>>         }
>>         else if( name.equals("interwikilinks") )
>>         {
>>             StringBuffer res = new StringBuffer();
>>
>>             for( Iterator i = 
>> context.getEngine().getAllInterWikiLinks().iterator(); i.hasNext(); )
>>             {
>>                 if( res.length() > 0 ) res.append(", ");
>>                 String link = (String) i.next();
>>                 res.append( link );
>>                 res.append( " --> " );
>>                 res.append( context.getEngine().getInterWikiURL(link) );
>>             }
>>             return res.toString();
>>         }
>>         else if( name.equals("inlinedimages") )
>>         {
>>             StringBuffer res = new StringBuffer();
>>
>>             for( Iterator i = 
>> context.getEngine().getAllInlinedImagePatterns().iterator(); 
>> i.hasNext(); )
>>             {
>>                 if( res.length() > 0 ) res.append(", ");
>>
>>                 String ptrn = (String) i.next();
>>                 res.append(ptrn);
>>             }
>>
>>             return res.toString();
>>         }
>>         else if( name.equals("pluginpath") )
>>         {
>>             String s = context.getEngine().getPluginSearchPath();
>>
>>             return (s == null) ? "-" : s;
>>         }
>>         else if( name.equals("baseurl") )
>>         {
>>             return context.getEngine().getBaseURL();
>>         }
>>         else if( name.equals("uptime") )
>>         {
>>             Date now = new Date();
>>             long secondsRunning = (now.getTime() - 
>> context.getEngine().getStartTime().getTime())/1000L;
>>
>>             long seconds = secondsRunning % 60;
>>             long minutes = (secondsRunning /= 60) % 60;
>>             long hours   = (secondsRunning /= 60) % 24;
>>             long days    = secondsRunning /= 24;
>>
>>             return days+"d, "+hours+"h "+minutes+"m "+seconds+"s";
>>         }
>>         else if( name.equals("loginstatus") )
>>         {
>>             WikiSession session = context.getWikiSession();
>>             return session.getStatus();
>>         }
>>         else if( name.equals("username") )
>>         {
>>             Principal wup = context.getCurrentUser();
>>
>>             return wup != null ? wup.getName() : "not logged in";
>>         }
>>         else if( name.equals("requestcontext") )
>>         {
>>             return context.getRequestContext();
>>         }
>>         else if( name.equals("pagefilters") )
>>         {
>>             List filters = 
>> context.getEngine().getFilterManager().getFilterList();
>>             StringBuffer sb = new StringBuffer();
>>
>>             for( Iterator i = filters.iterator(); i.hasNext(); )
>>             {
>>                 PageFilter pf = (PageFilter)i.next();
>>                 String f = pf.getClass().getName();
>>
>>                 if( pf instanceof InternalModule )
>>                     continue;
>>
>>                 if( sb.length() > 0 ) sb.append(", ");
>>                 sb.append( f );
>>             }
>>
>>             return sb.toString();
>>         }
>>         else
>>         {
>>             //
>>             // Check if such a context variable exists,
>>             // returning its string representation.
>>             //
>>             if( (context.getVariable( varName )) != null )
>>             {
>>                 return context.getVariable( varName ).toString();
>>             }
>>
>>             //
>>             //  Well, I guess it wasn't a final straw.  We also allow
>>             //  variables from the session and the request (in this 
>> order).
>>             //
>>
>>             HttpServletRequest req = context.getHttpRequest();
>>             if( req != null && req.getSession() != null )
>>             {
>>                 HttpSession session = req.getSession();
>>
>>                 try
>>                 {
>>                     String s;
>>
>>                     if( (s = (String)session.getAttribute( varName )) 
>> != null )
>>                         return s;
>>
>>                     if( (s = context.getHttpParameter( varName )) != 
>> null )
>>                         return s;
>>                 }
>>                 catch( ClassCastException e ) {}
>>             }
>>
>>             // And the final straw: see if the current page has named 
>> metadata.
>>
>>             WikiPage pg = context.getPage();
>>             if( pg != null )
>>             {
>>                 Object metadata = pg.getAttribute( varName );
>>                 if( metadata != null )
>>                     return metadata.toString();
>>             }
>>
>>             // And the final straw part 2: see if the "real" current 
>> page has
>>             // named metadata. This allows a parent page to control a 
>> inserted
>>             // page through defining variables
>>             WikiPage rpg = context.getRealPage();
>>             if( rpg != null )
>>             {
>>                 Object metadata = rpg.getAttribute( varName );
>>                 if( metadata != null )
>>                     return metadata.toString();
>>             }
>>
>>             // Next-to-final straw: attempt to fetch using property name
>>             // We don't allow fetching any other properties than 
>> those starting
>>             // with "jspwiki.".  I know my own code, but I can't 
>> vouch for bugs
>>             // in other people's code... :-)
>>
>>             Properties props = context.getEngine().getWikiProperties();
>>             if( varName.startsWith("jspwiki.") )
>>             {
>>
>>                 String s = props.getProperty( varName );
>>                 if( s != null )
>>                 {
>>                     return s;
>>                 }
>>             }
>>             // Our local preference: be able to define Aliases in 
>> properties to simplify long and repeated plugins!
>>             else if ((varName.length() > 1) && 
>> (varName.charAt(varName.length()-1) == '$')) {
>>                 String s = props.getProperty( 
>> "alias."+varName.substring( 0, varName.length()-1 ));
>>                 if( s != null )
>>                 {
>>                     return makeHTML( context, s );
>>                 }
>>                throw new NoSuchVariableException( "No alias 
>> "+varName.substring( 0, varName.length()-1 )+" defined in JSPWiki 
>> properties." );
>>             }
>>
>>             //
>>             //  Final defaults for some known quantities.
>>             //
>>
>>             if( varName.equals( VAR_ERROR ) || varName.equals( 
>> VAR_MSG ) )
>>                 return "";
>>
>>             throw new NoSuchVariableException( "No variable 
>> "+varName+" defined." );
>>         }
>>     }
>>
>> }
>
>
>
>


Re: Aliasing long Wiki markup

Posted by Janne Jalkanen <Ja...@ecyrd.com>.
Again, JIRA and patches.

But frankly, I would really hesitate to add something like this.  It  
opens up a can of worms.  Macros can make life very complicated, so  
this needs a lot more design than this.

/Janne

On Feb 15, 2008, at 10:10 , Christophe Dupriez wrote:

> Hi Again!
>
> When users are putting often the same long markup sequences, it may  
> be useful to define "aliases".
>
> Attached modifications allows to:
>
> 1) define aliases in jspwiki.properties. For instance:
>   #Applications shortcuts
>   alias.citedby=[{ReferringPagesPlugin title='!Cited by:%n'  
> exclude='Main,LeftMenu'}]
>
> 2) Call those alliases in pages: the syntax is the same than for  
> variable inclusion but a "$" sign is added at the end.
>   For instance: [{$citedby$}]
>   The WikiMarkup inside the alias is interpreted.
>
> The nice thing is also that you can change the definition of an  
> Alias without changing the wiki pages...
>
> Final note: \n is allowed in jspwiki.properties to indicate a end  
> of line (\n\n for end of paragraph)
>
> Attached source code is for 2.6.1. VariableContent.java is in the  
> "parser" directory.
>
> Have a nice day!
>
> Christophe
> /*
>     JSPWiki - a JSP-based WikiWiki clone.
>
>     Copyright (C) 2001 Janne Jalkanen (Janne.Jalkanen@iki.fi)
>
>     This program is free software; you can redistribute it and/or  
> modify
>     it under the terms of the GNU Lesser General Public License as  
> published by
>     the Free Software Foundation; either version 2.1 of the  
> License, or
>     (at your option) any later version.
>
>     This program is distributed in the hope that it will be useful,
>     but WITHOUT ANY WARRANTY; without even the implied warranty of
>     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>     GNU Lesser General Public License for more details.
>
>     You should have received a copy of the GNU Lesser General  
> Public License
>     along with this program; if not, write to the Free Software
>     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA   
> 02111-1307  USA
>  */
> package com.ecyrd.jspwiki;
>
> import java.security.Principal;
> import java.util.Date;
> import java.util.Iterator;
> import java.util.List;
> import java.util.Properties;
> import java.io.IOException;
>
> import javax.servlet.http.HttpServletRequest;
> import javax.servlet.http.HttpSession;
>
> import com.ecyrd.jspwiki.filters.PageFilter;
> import com.ecyrd.jspwiki.modules.InternalModule;
>
> import com.ecyrd.jspwiki.render.RenderingManager;
> import com.ecyrd.jspwiki.parser.MarkupParser;
> import com.ecyrd.jspwiki.parser.WikiDocument;
>
> /**
>  *  Manages variables.  Variables are case-insensitive.  A list of all
>  *  available variables is on a Wiki page called "WikiVariables".
>  *
>  *  @author Janne Jalkanen
>  *  @since 1.9.20.
>  */
> public class VariableManager
> {
>     //private static Logger log = Logger.getLogger 
> ( VariableManager.class );
>
>     // FIXME: These are probably obsolete.
>     public static final String VAR_ERROR = "error";
>     public static final String VAR_MSG   = "msg";
>
>     /**
>      *  Contains a list of those properties that shall never be shown.
>      *  Put names here in lower case.
>      */
>
>     static final String[] THE_BIG_NO_NO_LIST = {
>         "jspwiki.auth.masterpassword"
>     };
>
>     /**
>      *  Creates a VariableManager object using the property list  
> given.
>      *  @param props The properties.
>      */
>     public VariableManager( Properties props )
>     {
>     }
>
>     /**
>      *  Returns true if the link is really command to insert
>      *  a variable.
>      *  <P>
>      *  Currently we just check if the link starts with "{$".
>      *
>      *  @param link The link text
>      *  @return true, if this represents a variable link.
>      */
>     public static boolean isVariableLink( String link )
>     {
>         return link.startsWith("{$");
>     }
>
>     /**
>      *  Parses the link and finds a value.  This is essentially used
>      *  once {@link #isVariableLink(String)} has found that the  
> link text
>      *  actually contains a variable.  For example, you could pass in
>      *  "{$username}" and get back "JanneJalkanen".
>      *
>      *  @param  context The WikiContext
>      *  @param  link    The link text containing the variable name.
>      *  @return The variable value.
>      *  @throws IllegalArgumentException If the format is not valid  
> (does not
>      *          start with "{$", is zero length, etc.)
>      *  @throws NoSuchVariableException If a variable is not known.
>      */
>     public String parseAndGetValue( WikiContext context,
>                                     String link )
>         throws IllegalArgumentException,
>                IOException,
>                NoSuchVariableException
>     {
>         if( !link.startsWith("{$") )
>             throw new IllegalArgumentException( "Link does not  
> start with {$" );
>
>         if( !link.endsWith("}") )
>             throw new IllegalArgumentException( "Link does not end  
> with }" );
>
>         String varName = link.substring(2,link.length()-1);
>
>         return getValue( context, varName.trim() );
>     }
>
>     /**
>      *  This method does in-place expansion of any variables.   
> However,
>      *  the expansion is not done twice, that is, a variable  
> containing text $variable
>      *  will not be expanded.
>      *  <P>
>      *  The variables should be in the same format ({$variablename}  
> as in the web
>      *  pages.
>      *
>      *  @param context The WikiContext of the current page.
>      *  @param source  The source string.
>      *  @return The source string with variables expanded.
>      */
>     // FIXME: somewhat slow.
>     public String expandVariables( WikiContext context,
>                                    String      source )
>     {
>         StringBuffer result = new StringBuffer();
>
>         for( int i = 0; i < source.length(); i++ )
>         {
>             if( source.charAt(i) == '{' )
>             {
>                 if( i < source.length()-2 && source.charAt(i+1) ==  
> '$' )
>                 {
>                     int end = source.indexOf( '}', i );
>
>                     if( end != -1 )
>                     {
>                         String varname = source.substring( i+2, end );
>                         String value;
>
>                         try
>                         {
>                             value = getValue( context, varname );
>                         }
>                         catch( IOException e )
>                         {
>                             value = e.getMessage();
>                         }
>                         catch( NoSuchVariableException e )
>                         {
>                             value = e.getMessage();
>                         }
>                         catch( IllegalArgumentException e )
>                         {
>                             value = e.getMessage();
>                         }
>
>                         result.append( value );
>                         i = end;
>                         continue;
>                     }
>                 }
>                 else
>                 {
>                     result.append( '{' );
>                 }
>             }
>             else
>             {
>                 result.append( source.charAt(i) );
>             }
>         }
>
>         return result.toString();
>     }
>
>     // Probably this should be a method of WikiContext...
>     private String makeHTML (WikiContext context, String wikitext)  
> throws IOException
>     {
>         String result = "";
>
>         RenderingManager mgr = context.getEngine 
> ().getRenderingManager();
>         MarkupParser parser = mgr.getParser(context, wikitext);
>         WikiDocument doc = parser.parse();
>         result = mgr.getHTML( context, doc );
>         return result;
>     }
>
>     /**
>      *  Returns the value of a named variable.  See {@link #getValue 
> (WikiContext, String)}.
>      *  The only difference is that this method does not throw an  
> exception, but it
>      *  returns the given default value instead.
>      *
>      *  @param context WikiContext
>      *  @param varName The name of the variable
>      *  @param defValue A default value.
>      *  @return The variable value, or if not found, the default  
> value.
>      */
>     public String getValue( WikiContext context, String varName,  
> String defValue )
>     {
>         try
>         {
>             return getValue( context, varName );
>         }
>         catch( NoSuchVariableException e )
>         {
>             return defValue;
>         }
>         catch( IOException e )
>         {
>             return defValue;
>         }
>     }
>
>     /**
>      *  Returns a value of the named variable.  The resolving order is
>      *  <ol>
>      *    <li>Known "constant" name, such as "pagename", etc.  This  
> is so
>      *        that pages could not override certain constants.
>      *    <li>WikiContext local variable.  This allows a programmer to
>      *        set a parameter which cannot be overridden by user.
>      *    <li>HTTP Session
>      *    <li>HTTP Request parameters
>      *    <li>WikiPage variable.  As set by the user with the SET  
> directive.
>      *    <li>jspwiki.properties
>      *  </ol>
>      *
>      *  Use this method only whenever you really need to have a  
> parameter that
>      *  can be overridden by anyone using the wiki.
>      *
>      *  @param context The WikiContext
>      *  @param varName Name of the variable.
>      *
>      *  @return The variable value.
>      *
>      *  @throws IllegalArgumentException If the name is somehow  
> broken.
>      *  @throws NoSuchVariableException If a variable is not known.
>      */
>     // FIXME: Currently a bit complicated.  Perhaps should use  
> reflection
>     //        or something to make an easy way of doing stuff.
>     public String getValue( WikiContext context,
>                             String      varName )
>         throws IllegalArgumentException,
>                IOException,
>                NoSuchVariableException
>     {
>         if( varName == null )
>             throw new IllegalArgumentException( "Null variable  
> name." );
>
>         if( varName.length() == 0 )
>             throw new IllegalArgumentException( "Zero length  
> variable name." );
>
>         // Faster than doing equalsIgnoreCase()
>         String name = varName.toLowerCase();
>
>         for( int i = 0; i < THE_BIG_NO_NO_LIST.length; i++ )
>         {
>             if( name.equals(THE_BIG_NO_NO_LIST[i]) )
>                 return ""; // FIXME: Should this be something  
> different?
>         }
>
>         if( name.equals("pagename") )
>         {
>             return context.getPage().getName();
>         }
>         else if( name.equals("applicationname") )
>         {
>             return context.getEngine().getApplicationName();
>         }
>         else if( name.equals("jspwikiversion") )
>         {
>             return Release.getVersionString();
>         }
>         else if( name.equals("encoding") )
>         {
>             return context.getEngine().getContentEncoding();
>         }
>         else if( name.equals("totalpages") )
>         {
>             return Integer.toString(context.getEngine().getPageCount 
> ());
>         }
>         else if( name.equals("pageprovider") )
>         {
>             return context.getEngine().getCurrentProvider();
>         }
>         else if( name.equals("pageproviderdescription") )
>         {
>             return context.getEngine().getCurrentProviderInfo();
>         }
>         else if( name.equals("attachmentprovider") )
>         {
>             WikiProvider p = context.getEngine 
> ().getAttachmentManager().getCurrentProvider();
>             return (p != null) ? p.getClass().getName() : "-";
>         }
>         else if( name.equals("attachmentproviderdescription") )
>         {
>             WikiProvider p = context.getEngine 
> ().getAttachmentManager().getCurrentProvider();
>
>             return (p != null) ? p.getProviderInfo() : "-";
>         }
>         else if( name.equals("interwikilinks") )
>         {
>             StringBuffer res = new StringBuffer();
>
>             for( Iterator i = context.getEngine 
> ().getAllInterWikiLinks().iterator(); i.hasNext(); )
>             {
>                 if( res.length() > 0 ) res.append(", ");
>                 String link = (String) i.next();
>                 res.append( link );
>                 res.append( " --> " );
>                 res.append( context.getEngine().getInterWikiURL 
> (link) );
>             }
>             return res.toString();
>         }
>         else if( name.equals("inlinedimages") )
>         {
>             StringBuffer res = new StringBuffer();
>
>             for( Iterator i = context.getEngine 
> ().getAllInlinedImagePatterns().iterator(); i.hasNext(); )
>             {
>                 if( res.length() > 0 ) res.append(", ");
>
>                 String ptrn = (String) i.next();
>                 res.append(ptrn);
>             }
>
>             return res.toString();
>         }
>         else if( name.equals("pluginpath") )
>         {
>             String s = context.getEngine().getPluginSearchPath();
>
>             return (s == null) ? "-" : s;
>         }
>         else if( name.equals("baseurl") )
>         {
>             return context.getEngine().getBaseURL();
>         }
>         else if( name.equals("uptime") )
>         {
>             Date now = new Date();
>             long secondsRunning = (now.getTime() - context.getEngine 
> ().getStartTime().getTime())/1000L;
>
>             long seconds = secondsRunning % 60;
>             long minutes = (secondsRunning /= 60) % 60;
>             long hours   = (secondsRunning /= 60) % 24;
>             long days    = secondsRunning /= 24;
>
>             return days+"d, "+hours+"h "+minutes+"m "+seconds+"s";
>         }
>         else if( name.equals("loginstatus") )
>         {
>             WikiSession session = context.getWikiSession();
>             return session.getStatus();
>         }
>         else if( name.equals("username") )
>         {
>             Principal wup = context.getCurrentUser();
>
>             return wup != null ? wup.getName() : "not logged in";
>         }
>         else if( name.equals("requestcontext") )
>         {
>             return context.getRequestContext();
>         }
>         else if( name.equals("pagefilters") )
>         {
>             List filters = context.getEngine().getFilterManager 
> ().getFilterList();
>             StringBuffer sb = new StringBuffer();
>
>             for( Iterator i = filters.iterator(); i.hasNext(); )
>             {
>                 PageFilter pf = (PageFilter)i.next();
>                 String f = pf.getClass().getName();
>
>                 if( pf instanceof InternalModule )
>                     continue;
>
>                 if( sb.length() > 0 ) sb.append(", ");
>                 sb.append( f );
>             }
>
>             return sb.toString();
>         }
>         else
>         {
>             //
>             // Check if such a context variable exists,
>             // returning its string representation.
>             //
>             if( (context.getVariable( varName )) != null )
>             {
>                 return context.getVariable( varName ).toString();
>             }
>
>             //
>             //  Well, I guess it wasn't a final straw.  We also allow
>             //  variables from the session and the request (in this  
> order).
>             //
>
>             HttpServletRequest req = context.getHttpRequest();
>             if( req != null && req.getSession() != null )
>             {
>                 HttpSession session = req.getSession();
>
>                 try
>                 {
>                     String s;
>
>                     if( (s = (String)session.getAttribute 
> ( varName )) != null )
>                         return s;
>
>                     if( (s = context.getHttpParameter( varName )) ! 
> = null )
>                         return s;
>                 }
>                 catch( ClassCastException e ) {}
>             }
>
>             // And the final straw: see if the current page has  
> named metadata.
>
>             WikiPage pg = context.getPage();
>             if( pg != null )
>             {
>                 Object metadata = pg.getAttribute( varName );
>                 if( metadata != null )
>                     return metadata.toString();
>             }
>
>             // And the final straw part 2: see if the "real"  
> current page has
>             // named metadata. This allows a parent page to control  
> a inserted
>             // page through defining variables
>             WikiPage rpg = context.getRealPage();
>             if( rpg != null )
>             {
>                 Object metadata = rpg.getAttribute( varName );
>                 if( metadata != null )
>                     return metadata.toString();
>             }
>
>             // Next-to-final straw: attempt to fetch using property  
> name
>             // We don't allow fetching any other properties than  
> those starting
>             // with "jspwiki.".  I know my own code, but I can't  
> vouch for bugs
>             // in other people's code... :-)
>
>             Properties props = context.getEngine().getWikiProperties 
> ();
>             if( varName.startsWith("jspwiki.") )
>             {
>
>                 String s = props.getProperty( varName );
>                 if( s != null )
>                 {
>                     return s;
>                 }
>             }
>             // Our local preference: be able to define Aliases in  
> properties to simplify long and repeated plugins!
>             else if ((varName.length() > 1) && (varName.charAt 
> (varName.length()-1) == '$')) {
>                 String s = props.getProperty 
> ( "alias."+varName.substring( 0, varName.length()-1 ));
>                 if( s != null )
>                 {
>                     return makeHTML( context, s );
>                 }
>                throw new NoSuchVariableException( "No alias  
> "+varName.substring( 0, varName.length()-1 )+" defined in JSPWiki  
> properties." );
>             }
>
>             //
>             //  Final defaults for some known quantities.
>             //
>
>             if( varName.equals( VAR_ERROR ) || varName.equals 
> ( VAR_MSG ) )
>                 return "";
>
>             throw new NoSuchVariableException( "No variable  
> "+varName+" defined." );
>         }
>     }
>
> }