Wiki source code of Extending XWiki Rendering

Last modified by Vincent Massol on 2024/03/27 13:35

Show last authors
1 {{box cssClass="floatinginfobox" title="**Contents**"}}
2 {{toc/}}
3 {{/box}}
4
5 = Adding a new Syntax =
6
7 You have 2 possibilities:
8
9 * You might want to add the ability to write page content using a new input Syntax. In this case you'll need to write a Parser.
10 * or you might want to be able to render page content in a new output Syntax. In this case you'll need to write a Renderer.
11
12 == Adding a Parser ==
13
14 To add a Parser, simply implement the Parser interface and register it as a component against the Component Manager.
15
16 Example:
17
18 {{code language="java"}}
19 public class MyParser implements Parser
20 {
21 private static final Syntax SYNTAX = new Syntax(new SyntaxType("mysyntax", "My Syntax"), "1.0");
22
23 public Syntax getSyntax()
24 {
25 return SYNTAX;
26 }
27
28 public XDOM parse(Reader source) throws ParseException
29 {
30 XDOM xdom = new XDOM(Collections.singletonList(new WordBlock("amazing")));
31 return xdom;
32 }
33 }
34 {{/code}}
35
36 In practice how the contributed Parser is implemented is left to the implementer.
37
38 More precisely we support several strategies:
39
40 * Using {{scm project="xwiki-rendering" path="xwiki-rendering-wikimodel"}}WikiModel{{/scm}}. Historically this project was used as an external dependency of XWiki Rendering and was providing Parser implementations for various syntaxes. We have coded a {{scm project="xwiki-rendering" path="xwiki-rendering-syntax-wikimodel"}}WikiModel bridge{{/scm}} to convert WikiModel events to XWiki Rendering events. However since WikiModel wasn't really active and maintained (except by a few XWiki Rendering developers), we decided to fork the WikiModel's sources in the XWiki Rendering sources in the {{scm project="xwiki-rendering" path="xwiki-rendering-wikimodel"}}xwiki-rendering-wikimodel{{/scm}} module. The goal in the future is to refactor this module and spread the code in various existing modules. For example this module uses JavaCC to generate Java source from grammar files. At the moment the {{scm project="xwiki-rendering" path="xwiki-rendering-wikimodel/src/main/javacc"}}JavaCC grammars{{/scm}} are still located in that module but the plan is to move them to the various ##xwiki-rendering-syntax-XXX## modules.
41 ** Examples of syntaxes using this strategy: XWiki 2.x syntaxes, Confluence syntax, MediaWiki syntax
42 * We have also coded a [[Doxia>>https://maven.apache.org/doxia/]] {{scm project="xwiki-rendering" path="xwiki-rendering-rendering-doxia"}}bridge{{/scm}} to allow using Doxia Parsers (the bridge converts Doxia events into XWiki Rendering events).
43 ** Examples of syntaxes using this strategy: Docbook, TeX
44 * Some syntaxes use specific third-party Parsers.
45 ** Examples of syntaxes using this strategy: Markdown (which uses [[PegDown>>https://github.com/sirthias/pegdown]]).
46 * Last, parsing code can be implemented directly in the XWiki Rendering syntax module.
47 ** Examples of syntaxes using this strategy: None at this stage but in the future we'll probably move the full HTML syntax parsing code in the ##xwiki-rendering-syntax-xhtml## module (the parsing code is currently mostly located in ##xwiki-rendering-wikimodel## and a bit in ##xwiki-rendering-syntax-xhtml## too).
48
49 Make sure to check {{scm project="xwiki-rendering" path="xwiki-rendering-syntaxes"}}existing parser implementations{{/scm}}.
50
51 == Adding a Renderer ==
52
53 TODO: Add tutorial
54
55 You have to implement the [[Renderer interface>>https://github.com/xwiki/xwiki-rendering/blob/master/xwiki-rendering-api/src/main/java/org/xwiki/rendering/renderer/Renderer.java]].
56 Examples of Renderer source code:
57
58 * {{scm project="xwiki-rendering" path="xwiki-rendering-syntaxes/xwiki-rendering-syntax-xhtml/src/main/java/org/xwiki/rendering/internal/renderer/xhtml/XHTMLRenderer.java"}}XHTML Renderer{{/scm}}
59 * {{scm project="xwiki-rendering" path="xwiki-rendering-syntaxes/xwiki-rendering-syntax-xwiki20/src/main/java/org/xwiki/rendering/internal/renderer/xwiki20/XWikiSyntaxRenderer.java"}}XWiki 2.0 Syntax Renderer{{/scm}}
60 * {{scm project="xwiki-rendering" path="xwiki-rendering-syntaxes/xwiki-rendering-syntax-event/src/main/java/org/xwiki/rendering/internal/renderer/event/EventRenderer.java"}}Events Renderer{{/scm}}
61
62 == Adding Tests ==
63
64 You'll need to write tests to verify that your Parser/Renderer work fine.
65
66 There are 2 Rendering test frameworks you can use (they're both located in the ##org.xwiki.rendering:xwiki-rendering-test## module):
67
68 * The [[Rendering Test Framework>>Main.Extending.RenderingTestFramework]]: Allows to easily write tests to assert that your Parser or Renderer does the right thing.
69 * The [[Compatibility Test Suite>>Main.Extending.CompatibilityTestSuite]]: A well-known suite of commmon Tests for all Syntaxes to pass.
70
71 == Best Practices ==
72
73 * ((({{version since="11.3RC1"}}There's now the concept of a Syntax Registry and new Syntaxes are expected to register themselves in that registry. This is achieved by implementing the ##Provider<List<Syntax>>## component role. For example to register a ##html/4.01## syntax you'd write:
74
75 {{code language="java"}}
76 @Component
77 @Named("html/4.01")
78 @Singleton
79 public class HTML401SyntaxProvider implements Provider<List<Syntax>>
80 {
81 /**
82 * HTML syntax type.
83 */
84 public static final SyntaxType HTML = new SyntaxType("html", "HTML");
85
86 /**
87 * HTML 4.01 syntax.
88 */
89 public static final Syntax HTML_4_01 = new Syntax(HTML, "4.01");
90
91 @Override
92 public List<Syntax> get()
93 {
94 return Collections.singletonList(HTML_4_01);
95 }
96 }
97 {{/code}}
98 {{/version}})))
99
100 = Adding a new Macro =
101
102 Follow the [[Macro Tutorial>>ExtendingMacro]].
103
104 = Adding a new Transformation =
105
106 To create a Transformation, create a Component implementing the ##org.xwiki.rendering.transformation.Transformation## interface. To make it even easier you can simply extend ##org.xwiki.rendering.transformation.AbstractTransformation##.
107
108 Example:
109
110 {{code language="java"}}
111 @Component
112 @Named("wikiword")
113 @Singleton
114 public class WikiWordTransformation extends AbstractTransformation
115 {
116 /**
117 * Regex Pattern to recognize a WikiWord.
118 */
119 private static final Pattern WIKIWORD_PATTERN = Pattern.compile(
120 "\\p{javaUpperCase}+\\p{javaLowerCase}+(\\p{javaUpperCase}\\p{javaLowerCase}*)+");
121
122 /**
123 * Used to filter protected blocks (code macro marker block, etc).
124 */
125 private ProtectedBlockFilter filter = new ProtectedBlockFilter();
126
127 @Override
128 public void transform(Block block, TransformationContext transformationContext) throws TransformationException
129 {
130 // Find all Word blocks and for each of them check if they're a wiki word or not
131 for (WordBlock wordBlock : this.filter.getChildrenByType(block, WordBlock.class, true)) {
132 Matcher matcher = WIKIWORD_PATTERN.matcher(wordBlock.getWord());
133 if (matcher.matches()) {
134 ResourceReference linkReference = new DocumentResourceReference(wordBlock.getWord());
135 wordBlock.getParent().replaceChild(new LinkBlock(wordBlock.getChildren(), linkReference, false),
136 wordBlock);
137 }
138 }
139 }
140 }
141 {{/code}}
142
143 Check out the [[full code with tests>>https://github.com/xwiki/xwiki-rendering/tree/master/xwiki-rendering-transformations/xwiki-rendering-transformation-wikiword]]
144
145 = Adding a new Link Type =
146
147 When using the XWiki Syntax 2.1, it's possible to extend the link syntax. The generic link syntax is: ##{{{[[label>>referenceType:referencePath]]}}}## and it's possible to add new ##referenceType##. This is a several step process:
148
149 * Implement a component with the ##org.xwiki.rendering.parser.ResourceReferenceTypeParser## role. This is used to convert from a String to a ResourceReference. Here's is the source code for {{scm project="xwiki-rendering" path="xwiki-rendering-api/src/main/java/org/xwiki/rendering/internal/parser/reference/type"}}current implementations{{/scm}}.
150 * Implement a component with the ##org.xwiki.rendering.internal.renderer.xhtml.link.XHTMLLinkTypeRenderer## role. This is used when rendering a link (i.e. a ResourceReference) into XHTML. Here's is the source code for {{scm project="xwiki-rendering" path="xwiki-rendering-syntaxes/xwiki-rendering-syntax-xhtml/src/main/java/org/xwiki/rendering/internal/renderer/xhtml/link"}}current implementations{{/scm}}.
151
152 You can also [[configure the WYSIWYG editor to be able to use the new Link Type>>extensions:Extension.CKEditor Integration.Customization.WebHome#HAddanewLinkType]].
153
154 = Adding a new Image Type =
155
156 When using the XWiki Syntax 2.1 and starting with XWiki 5.4, it's possible to extend the image syntax. The generic image syntax is: ##{{{[[image:referenceType:referencePath]]}}}## and it's possible to add new ##referenceType##. This is a several step process:
157
158 * Implement a component with the ##org.xwiki.rendering.parser.ResourceReferenceTypeParser## role. This is used to convert from a String to a ResourceReference. Here's is the source code for {{scm project="xwiki-rendering" path="xwiki-rendering-api/src/main/java/org/xwiki/rendering/internal/parser/reference/type"}}current implementations{{/scm}}.
159 * Implement a component with the ##org.xwiki.rendering.internal.renderer.xhtml.image.XHTMLImageTypeRenderer## role. This is used when rendering an image (i.e. a ResourceReference) into XHTML. Here's the source code for {{scm project="xwiki-rendering" path="xwiki-rendering-syntaxes/xwiki-rendering-syntax-xhtml/src/main/java/org/xwiki/rendering/internal/renderer/xhtml/image"}}current implementations{{/scm}}.
  • Powered by XWiki 14.10.18-node2. Hosted and managed by XWiki SAS

Get Connected