velocity-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Nathan Bubna <nbu...@gmail.com>
Subject Re: Velocity Tools kills spring macros
Date Tue, 10 Feb 2009 20:31:15 GMT
Oh, and i should mention that i was using this with a trunk build.  It
might work with Tools 2.0-beta3, but i can't remember offhand.  If you
need a trunk build, ping me and i'll drop one on
people.apache.org/~nbubna

On Tue, Feb 10, 2009 at 12:29 PM, Nathan Bubna <nbubna@gmail.com> wrote:
> Hi Paul,
>
> I'm still not sure why this is happening and haven't found the time to
> figure it out.  Really, the spring-velocity code is not up to speed
> with VelocityTools 2, so it's a bit rough.  Here's some code i wrote a
> couple months back for Tools 2 to work better with Spring.  I haven't
> run it lately, but it may be helpful.  I've put it inline as well, in
> case the attachments are stripped.
>
> /*
>  * Copyright 2002-2007 the original author or authors.
>  *
>  * Licensed under the Apache License, Version 2.0 (the "License");
>  * you may not use this file except in compliance with the License.
>  * You may obtain a copy of the License at
>  *
>  *      http://www.apache.org/licenses/LICENSE-2.0
>  *
>  * Unless required by applicable law or agreed to in writing, software
>  * distributed under the License is distributed on an "AS IS" BASIS,
>  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>  * See the License for the specific language governing permissions and
>  * limitations under the License.
>  */
>
> package com.esha.cara.web;
> //package org.springframework.web.servlet.view.velocity;
>
> import java.util.Iterator;
> import java.util.Map;
>
> import javax.servlet.ServletContext;
> import javax.servlet.http.HttpServletRequest;
> import javax.servlet.http.HttpServletResponse;
>
> import org.apache.velocity.app.VelocityEngine;
> import org.apache.velocity.context.Context;
> import org.apache.velocity.tools.config.FactoryConfiguration;
> import org.apache.velocity.tools.view.VelocityView;
> import org.apache.velocity.tools.view.ServletUtils;
>
> import org.springframework.beans.BeansException;
> import org.springframework.context.ApplicationContextException;
> import org.springframework.web.servlet.view.velocity.VelocityToolboxView;
>
> /**
>  * {@link VelocityView} subclass which adds support for Velocity Tools toolboxes
>  * and Velocity Tools ViewTool callbacks / Velocity Tools 1.3 init methods.
>  *
>  * <p>Specify a "toolboxConfigLocation", for example "/WEB-INF/tools.xml",
>  * to automatically load a Velocity Tools toolbox definition file and expose
>  * all defined tools in the specified scopes. If no config location is
>  * specified, no toolbox will be loaded and exposed.
>  *
>  * <p>This view will always create a special Velocity context, namely an
>  * instance of the ChainedContext class which is part of the view package
>  * of Velocity tools. This allows to use tools from the view package of
>  * Velocity Tools, like LinkTool, which need to be initialized with a special
>  * context that implements the ViewContext interface (i.e. a ChainedContext).
>  *
>  * <p>This view also checks tools that are specified as "toolAttributes":
>  * If they implement the ViewTool interface, they will get initialized with
>  * the Velocity context. This allows tools from the view package of Velocity
>  * Tools, such as LinkTool, to be defined as
>  * {@link #setToolAttributes "toolAttributes"} on a VelocityToolboxView,
>  * instead of in a separate toolbox XML file.
>  *
>  * <p>This is a separate class mainly to avoid a required dependency on
>  * the view package of Velocity Tools in {@link VelocityView} itself.
>  * This class requires Velocity Tools 2.0 or higher.
>  *
>  * @author Juergen Hoeller
>  * @author Nathan Bubna
>  * @see #setFactoryConfiguration
>  * @see #initTool
>  * @see org.apache.velocity.tools.view.context.ViewContext
>  * @see org.apache.velocity.tools.view.tools.ViewTool
>  * @see org.apache.velocity.tools.view.tools.LinkTool
>  */
> public class VelocityToolsView extends VelocityToolboxView {
>
>    private FactoryConfiguration factoryConfig;
>    private org.apache.velocity.tools.view.VelocityView view;
>
>    public void setFactoryConfiguration(FactoryConfiguration config) {
>        this.factoryConfig = config;
>    }
>
>    /**
>     * Puts the FactoryConfiguration, if any, into the ServletContext's
>     * attributes for the VelocityView to find and then tries to create
>     * a org.apache.velocity.tools.view.VelocityView instance.
>     *
>     * @see FactoryConfiguration
>     * @see VelocityView
>     * @see #getServletContext()
>     */
>    protected void initApplicationContext() throws BeansException {
>        ServletContext app = getServletContext();
>
>        if (getToolboxConfigLocation() != null) {
>            FactoryConfiguration config =
>
> ServletUtils.getConfiguration(getToolboxConfigLocation(), app, true);
>            if (this.factoryConfig != null) {
>                this.factoryConfig.addConfiguration(config);
>            } else {
>                this.factoryConfig = config;
>            }
>        }
>
>        if (this.factoryConfig != null) {
>            // push the factory configuration into the servlet context
>            // where the VelocityView can find and use it
>            app.setAttribute(VelocityView.TOOLS_KEY, this.factoryConfig);
>        }
>
>        // get/create the VelocityView
>        this.view = ServletUtils.getVelocityView(app);
>
>        super.initApplicationContext();
>    }
>
>    /**
>     * Autodetect a VelocityEngine via the ApplicationContext or
>     * the org.apache.velocity.tools.view.VelocityView for this instance.
>     * Called if no explicit VelocityEngine has been specified.
>     * @return the VelocityEngine to use for VelocityViews
>     * @throws BeansException if no VelocityEngine could be found
>     * @see #getApplicationContext
>     * @see #setVelocityEngine
>     * @see org.apache.velocity.tools.view.VelocityView
>     * @see ServletUtils#getVelocityView(ServletContext,boolean)
>     */
>    protected VelocityEngine autodetectVelocityEngine() throws BeansException {
>        try {
>            VelocityEngine engine = super.autodetectVelocityEngine();
>            if (engine != null) {
>                // make sure VelocityView and Spring use the same engine
>                view.setVelocityEngine(engine);
>            }
>            return engine;
>        }
>        catch (ApplicationContextException ace) {
>            // use the VelocityView-created engine
>            return view.getVelocityEngine();
>        }
>    }
>
>    protected org.apache.velocity.tools.view.VelocityView getVelocityView() {
>        return this.view;
>    }
>
>    /**
>     * Overridden to create a ChainedContext, which is part of the view package
>     * of Velocity Tools, as special context. ChainedContext is needed for
>     * initialization of ViewTool instances.
>     * @see #initTool
>     */
>    protected Context createVelocityContext(Map model,
>                                            HttpServletRequest request,
>                                            HttpServletResponse
> response) throws Exception {
>        Context ctx = view.createContext(request, response);
>
>        //NOTE: this assumes that the model is ready to go...
>        if (!model.isEmpty()) {
>            for (Iterator i = model.entrySet().iterator(); i.hasNext(); ) {
>                Map.Entry entry = (Map.Entry)i.next();
>                ctx.put(String.valueOf(entry.getKey()), entry.getValue());
>            }
>        }
>        return ctx;
>    }
>
> }
>
>
> /*
>  * Copyright 2002-2006 the original author or authors.
>  *
>  * Licensed under the Apache License, Version 2.0 (the "License");
>  * you may not use this file except in compliance with the License.
>  * You may obtain a copy of the License at
>  *
>  *      http://www.apache.org/licenses/LICENSE-2.0
>  *
>  * Unless required by applicable law or agreed to in writing, software
>  * distributed under the License is distributed on an "AS IS" BASIS,
>  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>  * See the License for the specific language governing permissions and
>  * limitations under the License.
>  */
>
> package com.esha.cara.web;
> //package org.springframework.web.servlet.view.velocity;
>
> import java.io.StringWriter;
> import javax.servlet.http.HttpServletResponse;
> import org.apache.velocity.Template;
> import org.apache.velocity.context.Context;
> import org.apache.velocity.exception.ResourceNotFoundException;
> import org.springframework.context.ApplicationContextException;
>
> /**
>  * VelocityToolsLayoutView emulates the functionality offered by Velocity's
>  * VelocityLayoutServlet to ease page composition from different templates.
>  *
>  * <p>The <code>url</code> property should be set to the content template
>  * for the view, and the layout template location should be specified as
>  * <code>layoutUrl</code> property. A view can override the configured
>  * layout template location by setting the appropriate key (the default
>  * is "layout") in the content template.
>  *
>  * <p>When the view is rendered, the VelocityContext is first merged with
>  * the content template (specified by the <code>url</code> property) and
>  * then merged with the layout template to produce the final output.
>  *
>  * <p>The layout template can include the screen content through a
>  * VelocityContext variable (the default is "screen_content").
>  * At runtime, this variable will contain the rendered content template.
>  *
>  * @author Darren Davison
>  * @author Juergen Hoeller
>  * @author Nathan Bubna
>  * @see #setLayoutUrl
>  * @see #setLayoutKey
>  * @see #setScreenContentKey
>  */
> public class VelocityToolsLayoutView extends VelocityToolsView {
>
>    /**
>     * The default {@link #setLayoutUrl(String) layout url}.
>     */
>    public static final String DEFAULT_LAYOUT_URL = "layout.vm";
>
>    /**
>     * The default {@link #setLayoutKey(String) layout key}.
>     */
>    public static final String DEFAULT_LAYOUT_KEY = "layout";
>
>    /**
>     * The default {@link #setScreenContentKey(String) screen content key}.
>     */
>    public static final String DEFAULT_SCREEN_CONTENT_KEY = "screen_content";
>
>
>    private String layoutUrl = DEFAULT_LAYOUT_URL;
>
>    private String layoutKey = DEFAULT_LAYOUT_KEY;
>
>    private String screenContentKey = DEFAULT_SCREEN_CONTENT_KEY;
>
>
>    /**
>     * Set the layout template to use. Default is {@link
> #DEFAULT_LAYOUT_URL "layout.vm"}.
>     * @param layoutUrl the template location (relative to the template
>     * root directory)
>     */
>    public void setLayoutUrl(String layoutUrl) {
>        this.layoutUrl = layoutUrl;
>    }
>
>    /**
>     * Set the context key used to specify an alternate layout to be
> used instead
>     * of the default layout. Screen content templates can override the layout
>     * template that they wish to be wrapped with by setting this value in the
>     * template, for example:<br>
>     * <code>#set( $layout = "MyLayout.vm" )</code>
>     * <p>Default key is {@link #DEFAULT_LAYOUT_KEY "layout"}, as
> illustrated above.
>     * @param layoutKey the name of the key you wish to use in your
>     * screen content templates to override the layout template
>     */
>    public void setLayoutKey(String layoutKey) {
>        this.layoutKey = layoutKey;
>    }
>
>    /**
>     * Set the name of the context key that will hold the content of
>     * the screen within the layout template. This key must be present
>     * in the layout template for the current screen to be rendered.
>     * <p>Default is {@link #DEFAULT_SCREEN_CONTENT_KEY "screen_content"}:
>     * accessed in VTL as <code>$screen_content</code>.
>     * @param screenContentKey the name of the screen content key to use
>     */
>    public void setScreenContentKey(String screenContentKey) {
>        this.screenContentKey = screenContentKey;
>    }
>
>
>    /**
>     * Overrides <code>VelocityView.checkTemplate()</code> to additionally
check
>     * that both the layout template and the screen content template
> can be loaded.
>     * Note that during rendering of the screen content, the layout template
>     * can be changed which may invalidate any early checking done here.
>     */
>    protected void checkTemplate() throws ApplicationContextException {
>        super.checkTemplate();
>
>        try {
>            // Check that we can get the template, even if we might
> subsequently get it again.
>            getTemplate(this.layoutUrl);
>        }
>        catch (ResourceNotFoundException ex) {
>            throw new ApplicationContextException("Cannot find
> Velocity template for URL [" + this.layoutUrl +
>                    "]: Did you specify the correct resource loader path?", ex);
>        }
>        catch (Exception ex) {
>            throw new ApplicationContextException(
>                    "Could not load Velocity template for URL [" +
> this.layoutUrl + "]", ex);
>        }
>    }
>
>    /**
>     * Overrides the normal rendering process in order to pre-process
> the Context,
>     * merging it with the screen template into a single value
> (identified by the
>     * value of screenContentKey). The layout template is then merged with the
>     * modified Context in the super class.
>     */
>    protected void doRender(Context context, HttpServletResponse
> response) throws Exception {
>        renderScreenContent(context);
>
>        // Velocity context now includes any mappings that were defined
>        // (via #set) in screen content template.
>        // The screen template can overrule the layout by doing
>        // #set( $layout = "MyLayout.vm" )
>        String layoutUrlToUse = (String) context.get(this.layoutKey);
>        if (layoutUrlToUse != null) {
>            if (logger.isDebugEnabled()) {
>                logger.debug("Screen content template has requested
> layout [" + layoutUrlToUse + "]");
>            }
>        }
>        else {
>            // No explicit layout URL given -> use default layout of this view.
>            layoutUrlToUse = this.layoutUrl;
>        }
>
>        mergeTemplate(getTemplate(layoutUrlToUse), context, response);
>    }
>
>    /**
>     * The resulting context contains any mappings from render, plus
> screen content.
>     */
>    private void renderScreenContent(Context velocityContext) throws Exception {
>        if (logger.isDebugEnabled()) {
>            logger.debug("Rendering screen content template [" +
> getUrl() + "]");
>        }
>
>        StringWriter sw = new StringWriter();
>        Template screenContentTemplate = getTemplate(getUrl());
>        screenContentTemplate.merge(velocityContext, sw);
>
>        // Put rendered content into Velocity context.
>        velocityContext.put(this.screenContentKey, sw.toString());
>    }
>
> }
>

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


Mime
View raw message