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 ([EMAIL PROTECTED])

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 [EMAIL PROTECTED] #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 [EMAIL PROTECTED] #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." );
        }
    }

}






Reply via email to