Skip to content

Instantly share code, notes, and snippets.

@kand
Last active December 2, 2022 21:17
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save kand/4999238 to your computer and use it in GitHub Desktop.
Save kand/4999238 to your computer and use it in GitHub Desktop.
Sometimes nested paragraph systems are needed for special layout type components in CQ5. Here is a custom paragraph system that will overcome the issues related to nesting out of the box paragraph systems.
/**
* cellSearchPathModifier
* To be called on render by a cq:listeners listener handle for a parsys.
* Takes in the constructor for that parsys and modifies the search path
* for the components that can be inserted into that parsys. This function
* will limit the search path to the outermost parsys so all inner parsys
* inherit allowed components from the main parsys.
*
*/
var cellSearchPathModifier = function(componentConstructor) {
var oldSearchPath = componentConstructor.cellSearchPath;
var split = oldSearchPath.split('/');
if(split.length >= 2) {
var newSearchPath = split[0] + '/' + split[1];
componentConstructor.cellSearchPath = newSearchPath;
}
};
<!-- Component that will wrap the actual paragraph system -->
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:Component"
jcr:title="Inner Parsys"
jcr:description="A paragraph system that inherits allowed components from top most parent paragraph system."
componentGroup=".hidden" />
<%@include file="/apps/your-project/components/global.jsp"%>
<%-- Store current design mode --%>
<% WCMMode wcmMode = WCMMode.fromRequest(slingRequest); %>
<c:set var="isDesignMode" value="<%=WCMMode.equals(WCMMode.DESIGN) %>" scope="request" />
<%-- Disable design mode for this component, then renable it, preventing the editBar from rendering in design mode --%>
<c:if test="${isDesignMode}"><% WCMMode.DISABLED.toRequest(slingRequest); %></c:if>
<cq:include path="innerParsys" resourceType="your-project/components/content/innerParsys/parsys" />
<% wcmMode.toRequest(slingRequest); %
<!-- standard inheritance of the out of the box paragraph system -->
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:Component"
jcr:title="Inner Parsys"
jcr:description="A paragraph system that inherits allowed components from top most parent paragraph system."
cq:isContainer="true"
sling:resourceSuperType="foundation/components/parsys"
componentGroup=".hidden"
allowedChildren="*" />
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
cq:actions="[text:Inner Parsys,_clear,insert]"
cq:dialogMode="floating"
cq:layout="rollover"
jcr:primaryType="cq:EditConfig">
<!-- call cellSearchPathModifier to modify the search path for allowed components -->
<cq:listeners
render="function(constructor) { cellSearchPathModifier(constructor); }"
jcr:primaryType="cq:EditListenersConfig"/>
</jcr:root>
<!-- standard inheritance of the out of the box paragraph system -->
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:Component"
jcr:title="New Inner Parsys"
cq:isContainer="true"
sling:resourceSuperType="foundation/components/parsys/new"
componentGroup=".hidden"/>
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
cq:actions="[_clear,insert]"
cq:dialogMode="floating"
cq:layout="rollover"
jcr:primaryType="cq:EditConfig">
<!-- call cellSearchPathModifier to modify the search path for allowed components -->
<cq:listeners
render="function(constructor) { cellSearchPathModifier(constructor); }"
jcr:primaryType="cq:EditListenersConfig"/>
</jcr:root>
.... (change starts on line 77)
case NORMAL:
// include 'normal' paragraph
IncludeOptions.getOptions(request, true).getCssClassNames().add("section");
// draw anchor if needed
/* NOTE:
This block is skipped because of issues with nested paragraph systems and this
get call causing extreme slowdowns. This block isn't very useful anyways, especially
with HTML5.
*/
if (false/*currentStyle.get("drawAnchors", false)*/) {
String path = par.getPath();
path = path.substring(path.indexOf(JcrConstants.JCR_CONTENT)
+ JcrConstants.JCR_CONTENT.length() + 1);
String anchorID = path.replace("/", "_").replace(":", "_");
%><a name="<%= anchorID %>" style="visibility:hidden"></a><%
}
%><sling:include resource="<%= par %>"/><%
break;
....
Set up your file structure for the innerParsys component:
innerParsys
-> parsys
-> new
- _cq_editConfig.xml
- .content.xml
- _cq_editConfig.xml
- .content.xml
- parsys.jsp
- .content.xml
- innerParsys.jsp
@normanzb
Copy link

thx for the sharing, we r experiencing the exactly same issue. one thing worth to mention is that cq is not just lock up the browser with the stupid over complex CSP algorithm, but also they retain the search result so the 2nd call can return immediately without re-calculatION, however this naive logic will never work when the nesting level goes too deep, it will kill the browser by just one shot becuz huge memory consumption...

@normanzb
Copy link

Totally don't understand the point of buying cq if cq doesn't support nested layout.
Any other CMS does the 1 layered layout very well without paying so much money

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment