You may have been trying to search the internet for an out of box solution to remove the single paragraph container for Touch UI, and have found something like removeSingleParagraphContainer. But however, this attribute was for the Classic UI and deprecated. From my knowledge, there isn’t anything out of the box that can remove the p single paragraph container tag. However, I have spent some time and found a very lucrative solution. Lets remove the p tag from the rich text editor!
In this article, we will step through my implementation for us to remove the p tag once and for all, from being rendered.
My solution to this problem will be dealt with in the backend, Sling Model. Some may argue that the solution can be done using Javascript, but that can be very troublesome. Let’s Keep it Simple Stupid (KISS). There’s one caveat to this approach; scroll to the bottom of the page to see what it is.
Follow my 3 steps below to remove the P tag wrapper from what is being produced by the cq/gui/components/authoring/dialog/richtext.
Step 1. Add Custom Option In the Paraformat Options
Under the _cq_dialog.xml, cq/gui/components/authoring/dialog/richtext, add a new format option under the paraformat list of options.
The selected paraformat option will be a custom HTML element that wraps onto the highlighted or selected text from the author. In this case, when the author have selected text, and then click on the new paraformat option, the Html will look something like this <notextformat>sometext</notextformat>.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | // new paraformt to be added into line:77 <notextformat jcr:primaryType="nt:unstructured" description="No - Text Format" tag="notextformat"/> // the complete _cq_dialog.xml configuration for the cq/gui/components/authoring/dialog/richtext // new paraformt to be added into line:77 <text jcr:primaryType="nt:unstructured" sling:resourceType="cq/gui/components/authoring/dialog/richtext" name="./text" useFixedInlineToolbar="{Boolean}true"> <rtePlugins jcr:primaryType="nt:unstructured"> <format jcr:primaryType="nt:unstructured" features="bold,italic"/> <justify jcr:primaryType="nt:unstructured" features="-"/> <links jcr:primaryType="nt:unstructured" features="modifylink,unlink"/> <lists jcr:primaryType="nt:unstructured" features="*"/> <paraformat jcr:primaryType="nt:unstructured" features="*"> <formats jcr:primaryType="nt:unstructured"> <default_p jcr:primaryType="nt:unstructured" description="Paragraph" tag="p"/> <default_h1 jcr:primaryType="nt:unstructured" description="Heading 1" tag="h1"/> <default_h2 jcr:primaryType="nt:unstructured" description="Heading 2" tag="h2"/> <default_h3 jcr:primaryType="nt:unstructured" description="Heading 3" tag="h3"/> <default_h4 jcr:primaryType="nt:unstructured" description="Heading 4" tag="h4"/> <default_h5 jcr:primaryType="nt:unstructured" description="Heading 5" tag="h5"/> <default_h6 jcr:primaryType="nt:unstructured" description="Heading 6" tag="h6"/> <default_blockquote jcr:primaryType="nt:unstructured" description="Quote" tag="blockquote"/> <default_pre jcr:primaryType="nt:unstructured" description="Preformatted" tag="pre"/> <notextformat jcr:primaryType="nt:unstructured" description="No - Text Format" tag="notextformat"/> </formats> </paraformat> </rtePlugins> <uiSettings jcr:primaryType="nt:unstructured"> <cui jcr:primaryType="nt:unstructured"> <inline jcr:primaryType="nt:unstructured" toolbar="[format#bold,format#italic,format#underline,#justify,#lists,links#modifylink,links#unlink,#paraformat]"> <popovers jcr:primaryType="nt:unstructured"> <justify jcr:primaryType="nt:unstructured" items="[justify#justifyleft,justify#justifycenter,justify#justifyright]" ref="justify"/> <lists jcr:primaryType="nt:unstructured" items="[lists#unordered,lists#ordered,lists#outdent,lists#indent]" ref="lists"/> <paraformat jcr:primaryType="nt:unstructured" items="paraformat:getFormats:paraformat-pulldown" ref="paraformat"/> </popovers> </inline> </cui> </uiSettings> </text> |
Step 2. Create the Backend, Sling Model, to Text Transform
The backend Sling Model will read the ./text property that has been set by the user’s input. Using the String.ReplaceAll(), we can replace all </?notextformat>, regex pattern, with nothing (meaning that this element will be removed).
For example <notextformat>sometext</notextformat>. -> sometext.
We next save the formatted text into a variable of , which can be used by sightly to display HTML on the page.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | package com.sourcedcode.core.models; import org.apache.sling.api.resource.Resource; import org.apache.sling.models.annotations.Default; import org.apache.sling.models.annotations.Model; import org.apache.sling.models.annotations.Optional; import org.apache.sling.models.annotations.injectorspecific.ValueMapValue; import javax.annotation.PostConstruct; @Model(adaptables=Resource.class) public class MyTextComponent { @Optional @ValueMapValue @Default(values = "") private String text; private String richText; @PostConstruct protected void init() { if (!text.isEmpty()) { richText = text.replaceAll("</?notextformat>", ""); } } public String getRichText() { return richText; } } |
Step 3. Render Text Transform from Sightly
Now finally we just need to utilise sightly to print the text transformed, richText, to the screen.
1 2 3 4 | <sly data-sly-use.myTextComponent="com.sourcedcode.core.models.MyTextComponent"/> ${myTextComponent.richText @ context='html'} <sly data-sly-use.templates="core/wcm/components/commons/v1/templates.html" data-sly-call="${templates.placeholder @ isEmpty = !myTextComponent.richText}"></sly> |
The caveat with this approach is that when you are trying to export JSON format from this component, you will be stuck with this block of text, <notextformat>sometext</notextformat>, unless if you text to transform the export as well.
The reason why I did not overwrite the JCR values is that I wanted to retain the natural editing experience for the authors. With my solution when the author decides to make changes to the rich text field, they would not have a werid experience.