Skip to content
Snippets Groups Projects
Commit 4a6dfdbf authored by Vincent Massol's avatar Vincent Massol
Browse files

XWIKI-13752: Introduce a new Context macro parameter to control the execution...

XWIKI-13752: Introduce a new Context macro parameter to control the execution environment for macros inside it
parent 2eee97c7
No related branches found
No related tags found
No related merge requests found
......@@ -41,6 +41,7 @@
import org.xwiki.rendering.macro.MacroContentParser;
import org.xwiki.rendering.macro.MacroExecutionException;
import org.xwiki.rendering.macro.context.ContextMacroParameters;
import org.xwiki.rendering.macro.context.TransformationContextMode;
import org.xwiki.rendering.macro.descriptor.DefaultContentDescriptor;
import org.xwiki.rendering.transformation.MacroTransformationContext;
import org.xwiki.rendering.transformation.TransformationContext;
......@@ -142,22 +143,32 @@ public List<Block> execute(ContextMacroParameters parameters, String content, Ma
XDOM xdom = this.contentParser.parse(content, context, false, metadata, false);
// Apply the transformations but with a Transformation Context having the XDOM of the passed document
// so that macros execute on the passed document's XDOM (e.g. the TOC macro will generate the toc for
// the passed document instead of the current document).
// Get the XDOM from the referenced doc but with Transformations applied so that all macro are executed
// and contribute XDOM elements.
DocumentModelBridge referencedDoc = this.documentAccessBridge.getDocument(referencedDocReference);
XDOM referencedXDOM = referencedDoc.getXDOM();
TransformationContext referencedTxContext =
new TransformationContext(referencedXDOM, referencedDoc.getSyntax());
this.transformationManager.performTransformations(referencedXDOM, referencedTxContext);
// Now execute transformation on the context macro content but with the referenced XDOM in the
// Transformation context!
TransformationContext txContext = new TransformationContext(referencedXDOM, referencedDoc.getSyntax());
this.transformationManager.performTransformations(xdom, txContext);
// Configure the Transformation Context depending on the mode asked.
if (parameters.getTransformationContext() == TransformationContextMode.DOCUMENT
|| parameters.getTransformationContext() == TransformationContextMode.TRANSFORMATIONS)
{
// Apply the transformations but with a Transformation Context having the XDOM of the passed
// document so that macros execute on the passed document's XDOM (e.g. the TOC macro will generate
// the toc for the passed document instead of the current document).
DocumentModelBridge referencedDoc = this.documentAccessBridge.getDocument(referencedDocReference);
XDOM referencedXDOM = referencedDoc.getXDOM();
if (parameters.getTransformationContext() == TransformationContextMode.TRANSFORMATIONS) {
// Get the XDOM from the referenced doc but with Transformations applied so that all macro are
// executed and contribute XDOM elements.
// IMPORTANT: This can be dangerous since it means executing macros, and thus also script macros
// defined in the referenced document. To be used with caution.
TransformationContext referencedTxContext =
new TransformationContext(referencedXDOM, referencedDoc.getSyntax());
this.transformationManager.performTransformations(referencedXDOM, referencedTxContext);
}
// Now execute transformation on the context macro content but with the referenced XDOM in the
// Transformation context!
TransformationContext txContext =
new TransformationContext(referencedXDOM, referencedDoc.getSyntax());
this.transformationManager.performTransformations(xdom, txContext);
}
// Keep metadata so that the result stay associated to context properties when inserted in the parent
// XDOM
......
......@@ -34,6 +34,13 @@ public class ContextMacroParameters
*/
private String documentReference;
/**
* @see #getTransformationContext()
* @since 8.3
* @since 8.4RC1
*/
private TransformationContextMode transformationContextMode = TransformationContextMode.CURRENT;
/**
* @return the reference to the document that will be set as the current document to evaluate the macro's content
*/
......@@ -51,4 +58,26 @@ public void setDocument(String documentReference)
this.documentReference = documentReference;
}
/**
* @return the mode to use for setting the Transformation Context in which the Context Macro will execute, see
* {@link TransformationContextMode} for details
* @since 8.3
* @since 8.4RC1
*/
public TransformationContextMode getTransformationContext()
{
return this.transformationContextMode;
}
/**
* @param mode refer to {@link #getTransformationContext()}
* @since 8.3
* @since 8.4RC1
*/
@PropertyDescription("The Transformation Context mode to use. "
+ "Valid values are \"current\", \"document\" and \"transformations\"")
public void setTransformationContext(TransformationContextMode mode)
{
this.transformationContextMode = mode;
}
}
/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This 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 software 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 software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.xwiki.rendering.macro.context;
/**
* Defines the strategy to use for setting the Transformation Context for the Context Macro. Namely this controls
* the context for the macros located inside the Context Macro. For example some macros will use as input the other
* XDOM elements before or after the current Macro block that they correspond to. For example the TOC macro executes
* late (with a low priority) so that all other macros have a chance to execute and then it looks for all Heading
* Blocks in the XDOM, from the root.
*
* @version $Id$
* @since 8.3
* @since 8.4RC1
*/
public enum TransformationContextMode
{
/**
* The XDOM on which the macros in the Context macro execute is the current document's XDOM.
*/
CURRENT,
/**
* The XDOM on which the macros in the Context macro execute is the referenced document's XDOM (but without
* transformations applied to that XDOM).
*/
DOCUMENT,
/**
* The XDOM on which the macros in the Context macro execute is the referenced document's XDOM but with
* transformations applied to that XDOM. IMPORTANT: This can be dangerous since it means executing macros, and thus
* also script macros defined in the referenced document. To be used with caution since that have side effects.
*/
TRANSFORMATIONS
}
......@@ -2,14 +2,14 @@
.#-----------------------------------------------------
.input|xwiki/2.1
.#-----------------------------------------------------
{{context document="Space.Page"}}
{{context document="Space.Page" transformationContext="transformations"}}
{{toc/}}
{{/context}}
.#-----------------------------------------------------
.expect|event/1.0
.#-----------------------------------------------------
beginDocument
beginMacroMarkerStandalone [context] [document=Space.Page] [{{toc/}}]
beginMacroMarkerStandalone [context] [document=Space.Page|transformationContext=transformations] [{{toc/}}]
beginMetaData [[base]=[Space.Page][source]=[Space.Page][syntax]=[XWiki 2.1]]
beginMacroMarkerStandalone [toc] []
beginList [BULLETED]
......@@ -28,5 +28,5 @@ endListItem
endList [BULLETED]
endMacroMarkerStandalone [toc] []
endMetaData [[base]=[Space.Page][source]=[Space.Page][syntax]=[XWiki 2.1]]
endMacroMarkerStandalone [context] [document=Space.Page] [{{toc/}}]
endMacroMarkerStandalone [context] [document=Space.Page|transformationContext=transformations] [{{toc/}}]
endDocument
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment