Issue Details (XML | Word | Printable)

Key: VELOCITY-532
Type: Bug Bug
Status: Resolved Resolved
Resolution: Cannot Reproduce
Priority: Major Major
Assignee: Unassigned
Reporter: Will Glass-Husain
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
Velocity

$velocityCount in macro not processed

Created: 25/Mar/07 12:25 AM   Updated: 03/Sep/08 06:05 AM
Return to search
Component/s: None
Affects Version/s: 1.5
Fix Version/s: 1.6

Time Tracking:
Not Specified

Issue Links:
Reference
 

Resolution Date: 03/Sep/08 06:05 AM


 Description  « Hide


---------- Forwarded message ----------
From: mraible <matt@raibledesigns.com>
Date: Mar 22, 2007 11:28 AM
Subject: Issue with $velocityCount in 1.5
To: user@velocity.apache.org



I've been using Velocity 1.4 for a couple of years now with great success.
Today, I tried to use Struts Menu 2.4.2 with Velocity 1.5 and found an issue
with $velocityCount not being properly processed. My template is below.

The problem occurs on the following line:

        #if ($velocityCount == $menu.parent.components.size())
          <li class="last">
        #else

With 1.4, $velocityCount turns into a number when the displayCssMenu macro
is called from #foreach. However, in 1.5, it's never turned into a number.

Any ideas?

Thanks,

Matt

#macro( displayCssMenu $menu )
  #if ($displayer.isAllowed($menu))
    ## set menu title
    #set ($title = $displayer.getMessage($menu.title))

    #if (!$menu.url) #set ($url="javascript:void(0)") #else #set
($url=$menu.url) #end

    ## create a single menu item
    #if ($menu.components.size() == 0)
        #if ($velocityCount == $menu.parent.components.size())
          <li class="last">
        #else
          <li>
        #end
        #if ($menu.name == $currentMenu)
           $url ${title}
        #else
           $url ${title}
        #end
    #else ## create multiple menu items in a menu
        #if ($menu.components.size() > 0)
            #set ($hasViewableChildren = false)
            #foreach ($menuIt in $menu.components)
                #if ($displayer.isAllowed($menuIt))
                    #set($hasViewableChildren = true)
                #end
            #end
        #end

        <li#if ($hasViewableChildren) class="menubar"#end>
           $url ${title}
    #end

    #if ($menu.components.size() > 0)
        #if ($hasViewableChildren)
          <ul>
        #end

        #foreach ($menuIt in $menu.components)
            #displayCssMenu($menuIt)
        #end

        #if ($hasViewableChildren && ($velocityCount ==
$menu.parent.components.size()))
          </ul>
        #else
          </li>
        #end
    #else
      </li>
      #if ($velocityCount == $menu.parent.components.size())
      </ul>
      #end
    #end
  #end
#end

#displayCssMenu($menu)
--
View this message in context: http://www.nabble.com/Issue-with-%24velocityCount-in-1.5-tf3449438.html#a9621118
Sent from the Velocity - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@velocity.apache.org
For additional commands, e-mail: user-help@velocity.apache.org



--
Forio Business Simulations
 
Will Glass-Husain
wglass@forio.com
www.forio.com


 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Will Glass-Husain made changes - 25/Mar/07 12:26 AM
Field Original Value New Value
Link This issue is related to VELOCITY-285 [ VELOCITY-285 ]
Matt Raible added a comment - 25/Mar/07 01:28 AM
Here's my velocity.properties:

# specify resource loaders to use
resource.loader = class, webapp

# NOTE: Change cache settings to set to false while developing - change to true when deploying to production.
# You'll need to copy this entire file into WEB-INF/classes to override any attributes.

# for the loader we call 'class', use the ClasspathResourceLoader
class.resource.loader.description = Velocity Classpath Resource Loader
class.resource.loader.class = org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
class.resource.loader.cache = true
class.resource.loader.modificationCheckInterval = 60

# for the loader we call 'webapp', use the WebappLoader
webapp.resource.loader.description = Velocity Webapp Loader
webapp.resource.loader.class = org.apache.velocity.tools.view.servlet.WebappLoader
webapp.resource.loader.cache = true
webapp.resource.loader.modificationCheckInterval = 60

# log invalid template references?
# set this to false to have a quieter velocity.log
runtime.log.invalid.reference=false

# velocimacro settings
velocimacro.library = net/sf/navigator/displayer/globalMacros.vm,menuMacros.vm
velocimacro.library.autoreload = true
velocimacro.permissions.allow.inline.to.replace.global = true

# load the local directive
userdirective=net.sf.navigator.displayer.LocalDirective

And LocalDirective.java:

/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2003 The Apache Software Foundation. All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in
 * the documentation and/or other materials provided with the
 * distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 * any, must include the following acknowlegement:
 * "This product includes software developed by the
 * Apache Software Foundation (http://www.apache.org/)."
 * Alternately, this acknowlegement may appear in the software itself,
 * if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Velocity", and "Apache Software
 * Foundation" must not be used to endorse or promote products derived
 * from this software without prior written permission. For written
 * permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 * nor may "Apache" appear in their names without prior written
 * permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation. For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package net.sf.navigator.displayer;

import org.apache.velocity.context.InternalContextAdapter;
import org.apache.velocity.runtime.parser.node.Node;
import org.apache.velocity.runtime.parser.node.SimpleNode;
import org.apache.velocity.runtime.directive.Directive;
import org.apache.velocity.runtime.parser.ParserTreeConstants;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.exception.ParseErrorException;

import org.apache.velocity.runtime.parser.node.ASTReference;

import java.io.Writer;
import java.io.IOException;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;


/**
 * Simple directive to provide ability to trap a local value for
 * iteration.
 *
 * Ex :
 *
 * #set($foo = 1)
 * $foo
 * #local($foo)
 * #set($foo = 2)
 * $foo
 * #end
 * $foo
 *
 * should output
 *
 * 1
 * 2
 * 1
 *
 * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
 * @version $Id: LocalDirective.java,v 1.1 2003/10/31 05:59:06 mraible Exp $
 */
public class LocalDirective extends Directive
{
    public String getName()
    {
        return "local";
    }

        public int getType()
        {
            return BLOCK;
        }

        public boolean render(InternalContextAdapter context,
                               Writer writer, Node node)
        throws IOException, MethodInvocationException, ResourceNotFoundException,
                ParseErrorException
        {
            Map data = new HashMap();

            int num = node.jjtGetNumChildren();

            /*
             * get the references
             */

            for (int i=0; i < num; i++)
            {
                SimpleNode child = (SimpleNode) node.jjtGetChild(i);

                /*
                 * if a block, just execute
                 */

                if (child.getType() == ParserTreeConstants.JJTBLOCK)
                {
                    child.render(context, writer);
                    break;
                }
                else
                {
                    /* save the values - for now, just w/ ref to test */

                    if (child.getType() == ParserTreeConstants.JJTREFERENCE)
                    {
                        data.put(child, child.execute(null, context));
                    }
                    else
                    {
                        System.out.println("unhandled type");
                    }
                }
            }

            Iterator it = data.keySet().iterator();

            while(it.hasNext())
            {
                ASTReference ref = (ASTReference) it.next();

                ref.setValue(context, data.get(ref));
            }

            return true;
        }
}

Nathan Bubna added a comment - 15/Aug/08 03:08 AM
Seems like this is likely to be related to VELOCITY-62. There appears to have been some regression here from 1.4; i'm not sure what caused this change.

I would still like to note that i consider this bad practice. If $velocityCount is relevant to the macro, it would be best passed in as an argument, rather than just hoping it is present.

Repository Revision Date User Message
ASF #691521 Wed Sep 03 06:03:31 UTC 2008 nbubna VELOCITY-532 add regression test case
Files Changed
ADD /velocity/engine/trunk/src/test/org/apache/velocity/test/issues/Velocity532TestCase.java

Nathan Bubna added a comment - 03/Sep/08 06:05 AM
I can't reproduce this with the current trunk (1.6-dev). Appears to have been fixed. Or else there's some nuance to the example code that i haven't replicated.

Nathan Bubna made changes - 03/Sep/08 06:05 AM
Resolution Cannot Reproduce [ 5 ]
Status Open [ 1 ] Resolved [ 5 ]