[
https://issues.apache.org/jira/browse/VELOCITY-586?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Will Glass-Husain resolved VELOCITY-586.
----------------------------------------
Resolution: Won't Fix
Thanks for sharing this.
Going to resolve this issue - I think we don't want to mix HTTP and #parse. But
it's a good custom directive if you need it.
An alternate way of doing this is to use IncludeEventHandler to redirect to a
"wrapper" page which includes this kind of info.
> Add debugging hooks to #parse
> -----------------------------
>
> Key: VELOCITY-586
> URL: https://issues.apache.org/jira/browse/VELOCITY-586
> Project: Velocity
> Issue Type: Improvement
> Components: Engine
> Affects Versions: 1.5
> Reporter: Tim White
> Priority: Minor
>
> When you have a page that is made up of a complex web of templates and
> #parsed includes, it is critical to be able to quickly see what parts of the
> page are really in what file.
> To do this, I've hacked #parse to inject debugging information into the
> template when a 'debug mode' is engaged. This debug mode is engaged via a
> URL parameter.
> I also inject this information in the VVS right before the main template is
> rendered. In this way, you can create a debug overlay on top of the page in
> your browser that shows you where each piece of text is coming from.
> I think this probably could better be implemented using hooks, so that a user
> could trigger when the debug information was being injected.
> I also suggest that the name of the current template, it's resource loader,
> etc. be passed into the context, so it can be used to see what template is
> where and what loader it came from.
> Finally, if there could be a way to conditionally prepend or append a
> template to each merged or #parse template, that could also help.
> Thanks!!!
> package org.apache.velocity.runtime.directive;
> /*
> * Licensed to the Apache Software Foundation (ASF) under one
> * or more contributor license agreements. See the NOTICE file
> * distributed with this work for additional information
> * regarding copyright ownership. The ASF licenses this file
> * to you 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.
> */
> import java.io.IOException;
> import java.io.Writer;
> import javax.servlet.http.HttpSession;
> import org.apache.velocity.Template;
> import org.apache.velocity.app.event.EventHandlerUtil;
> import org.apache.velocity.context.InternalContextAdapter;
> import org.apache.velocity.exception.MethodInvocationException;
> import org.apache.velocity.exception.ParseErrorException;
> import org.apache.velocity.exception.ResourceNotFoundException;
> import org.apache.velocity.runtime.RuntimeConstants;
> import org.apache.velocity.runtime.parser.node.Node;
> import org.apache.velocity.runtime.parser.node.SimpleNode;
> import com.qwest.velocity.VelocityConstants;
> /**
> * Pluggable directive that handles the <code>#parse()</code> statement in
> VTL.
> *
> * <pre>
> * Notes:
> * -----
> * 1) The parsed source material can only come from somewhere in
> * the TemplateRoot tree for security reasons. There is no way
> * around this. If you want to include content from elsewhere on
> * your disk, use a link from somwhere under Template Root to that
> * content.
> *
> * 2) There is a limited parse depth. It is set as a property
> * "parse_directive.maxdepth = 10" for example. There is a 20
> iteration
> * safety in the event that the parameter isn't set.
> * </pre>
> *
> * @author <a href="mailto:[email protected]">Geir Magnusson Jr.</a>
> * @author <a href="mailto:[email protected]">Jason van Zyl</a>
> * @author <a href="mailto:[email protected]">Christoph Reck</a>
> * @version $Id: Parse.java 463298 2006-10-12 16:10:32Z henning $
> */
> public class Parse extends InputBase {
> /**
> * Return name of this directive.
> *
> * @return The name of this directive.
> */
> public String getName() {
> return "parse";
> }
> /**
> * Return type of this directive.
> *
> * @return The type of this directive.
> */
> public int getType() {
> return LINE;
> }
> /**
> * iterates through the argument list and renders every argument that
> is appropriate. Any non appropriate arguments are logged, but render()
> continues.
> *
> * @param context
> * @param writer
> * @param node
> * @return True if the directive rendered successfully.
> * @throws IOException
> * @throws ResourceNotFoundException
> * @throws ParseErrorException
> * @throws MethodInvocationException
> */
> public boolean render(InternalContextAdapter context, Writer writer,
> Node node) throws IOException, ResourceNotFoundException,
> ParseErrorException, MethodInvocationException {
> /*
> * if rendering is no longer allowed (after a stop), we can
> safely skip execution of all the parse directives.
> */
> if (!context.getAllowRendering()) {
> return true;
> }
> /*
> * did we get an argument?
> */
> if (node.jjtGetChild(0) == null) {
> rsvc.getLog().error("Portal #parse() null argument");
> return false;
> }
> /*
> * does it have a value? If you have a null reference, then no.
> */
> Object value = node.jjtGetChild(0).value(context);
> if (value == null) {
> rsvc.getLog().error("Portal #parse() null argument");
> return false;
> }
> /*
> * get the path
> */
> String sourcearg = value.toString();
> /*
> * check to see if the argument will be changed by the event
> cartridge
> */
> String arg = EventHandlerUtil.includeEvent(rsvc, context,
> sourcearg, context.getCurrentTemplateName(), getName());
> /*
> * a null return value from the event cartridge indicates we
> should not input a resource.
> */
> boolean blockinput = false;
> if (arg == null)
> blockinput = true;
> /*
> * see if we have exceeded the configured depth. If it isn't
> configured, put a stop at 20 just in case.
> */
> Object[] templateStack = context.getTemplateNameStack();
> if (templateStack.length >=
> rsvc.getInt(RuntimeConstants.PARSE_DIRECTIVE_MAXDEPTH, 20)) {
> StringBuffer path = new StringBuffer();
> for (int i = 0; i < templateStack.length; ++i) {
> path.append(" > " + templateStack[i]);
> }
> rsvc.getLog().error("Portal #parse: Max recursion depth
> reached (" + templateStack.length + ')' + " File stack:" + path);
> return false;
> }
> /*
> * now use the Runtime resource loader to get the template
> */
> Template t = null;
> try {
> if (!blockinput)
> t = rsvc.getTemplate(arg,
> getInputEncoding(context));
> } catch (ResourceNotFoundException rnfe) {
> /*
> * the arg wasn't found. Note it and throw
> */
> rsvc.getLog().error("Portal #parse(): cannot find
> template '" + arg + "', called from template " +
> context.getCurrentTemplateName() + " at (" + getLine() + ", " + getColumn() +
> ")");
> throw rnfe;
> } catch (ParseErrorException pee) {
> /*
> * the arg was found, but didn't parse - syntax error
> note it and throw
> */
> rsvc.getLog().error(
> "Portal #parse(): syntax error in
> #parse()-ed template '" + arg + "', called from template " +
> context.getCurrentTemplateName() + " at (" + getLine() + ", " + getColumn() +
> ")");
> throw pee;
> }
> /**
> * pass through application level runtime exceptions
> */
> catch (RuntimeException e) {
> throw e;
> } catch (Exception e) {
> rsvc.getLog().error("Portal #parse() : arg = " + arg +
> '.', e);
> return false;
> }
> /*
> * and render it
> */
> try {
> if (rsvc.getLog().isDebugEnabled()) {
> rsvc.getLog().debug("*** Portal #Parse Template
> Path: " + t.getName());
> }
>
> /* Save the name of the main template before resetting
> templateName for this include */
> String mainTemplateName = "";
> if (context.get(VelocityConstants.TEMPLATE_NAME_VAR) !=
> null) {
> mainTemplateName =
> context.get(VelocityConstants.TEMPLATE_NAME_VAR).toString();
> }
> /* Set the name of the current template in the context
> for general use */
> context.put(VelocityConstants.TEMPLATE_NAME_VAR,
> t.getName());
> /* Check various places to see if debug mode is enabled
> */
> boolean debugMode = false;
> /* This supports PortalVelocityViewServlet */
> if (context.get(VelocityConstants.DEBUG_ATTRIBUTE) !=
> null) {
> debugMode = true;
> }
> /* This supports qcms.getMessage() */
> if (context.get("session") != null) {
> HttpSession session = (HttpSession)
> context.get("session");
> if (session.getAttribute("qCmsDebugger") !=
> null) {
> debugMode = true;
> }
> }
> /* Print Debug start output to browser if debug mode is
> on */
> if (debugMode) {
> Template startTemplate =
> rsvc.getTemplate(VelocityConstants.DEBUG_OUTLINE_START_TEMPLATE,
> getInputEncoding(context));
> startTemplate.merge(context, writer);
> Template nameTemplate =
> rsvc.getTemplate(VelocityConstants.DEBUG_NAME_TEMPLATE,
> getInputEncoding(context));
> nameTemplate.merge(context, writer);
> }
>
> if (!blockinput) {
> context.pushCurrentTemplateName(arg);
> ((SimpleNode) t.getData()).render(context,
> writer);
> }
>
> /* Print Debug end output to browser if debug mode is
> on */
> if (debugMode) {
> Template endTemplate =
> rsvc.getTemplate(VelocityConstants.DEBUG_OUTLINE_END_TEMPLATE,
> getInputEncoding(context));
> endTemplate.merge(context, writer);
> }
> /* Restore the templateName variable to match the main
> template name */
> context.put(VelocityConstants.TEMPLATE_NAME_VAR,
> mainTemplateName);
> }
> /*
> * if it's a MIE, it came from the render.... throw it...
> */
> catch (MethodInvocationException e) {
> throw e;
> }
> /**
> * pass through application level runtime exceptions
> */
> catch (RuntimeException e) {
> throw e;
> }
> catch (Exception e) {
> rsvc.getLog().error("Portal #parse: Exception rendering
> #parse(" + arg + ')', e);
> return false;
> } finally {
> if (!blockinput)
> context.popCurrentTemplateName();
> }
> /*
> * note - a blocked input is still a successful operation as
> this is expected behavior.
> */
> return true;
> }
> }
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]