Interception point on layout rendering

I’ve developed a module that provide a drag and drop functionality to change widget order on layout. It’s something similar to wordpress.

Here’s the code: https://github.com/contentbox-modules/widget-manager

The widget seems to work, howevere I want to know if there is some strategy to better handling widget rendering on layout.

As it is right now it listen for interception point and append to buffer the widgets.

Is there any interception point that I can use to render widets when layout is rendered, something similar to “cb_oncontentrendering”?

Wouldn’t your view do this?

Or am I not understanding what you’re asking.

I’m not sure.

I see that there is an interceptor “cb_oncontentrendering” that is fired when an entry or page is rendered.

Once fired it stores the result in cache, so that the page is stored in cache with all contentstre or widget rendered.

The layout instead does not have such a method, so on every request interceptors (cbui_beforesidebar, cbuui_ftersidebar etc…) are fired.

I want to know if there is a way to render widgets in layout at the first request, and then cache the rendered layoout with widgets. On further request there is no need to perform widget rendering because it’s already stored in cache.

My module instead has an interceptor that listen for every cbui_* interceptionpoint and tries to render widget.

I’m asking if there is a better approach to perform this.

Yeah still not sure I understand, but as you bring up cb_onContentRendering I will try to answer it the best way I can. But for your problem, your view should still be taking care of the widget rendering. Unless you are looking to change this on the fly later after everything has been rendered.

Which brings me to the interception point cb_onContentRendering, I no longer have my blog up so I will do my best to explain this here.

ContentBox (at least the last version I used), did not understand page breaks and I used this interception to process the content after it had been rendered, which is what this interception point is for. In some sites they have in their website the ability to have one content that would allow multiple pages for that content. Which I labelled as a page break for my example.

So with that I set out to write content in ContentBox that looked something like this in the editing of an entry.

This is paragraph 1 and Page 1

This is paragraph 2 and Page 1

This is paragraph 3 and Page 1

@@PageBreak@@

This is paragraph 1 and Page 2

This is paragraph 2 and Page 2

This is paragraph 3 and Page 2

@@PageBreak@@

This is paragraph 1 and Page 3

This is paragraph 2 and Page 3

This is paragraph 3 and Page 3

Once the views and everything had been rendered, the interceptor would then fire and do the magic that was needed. Which I have included the source code at the end. Other things I can see this interception point being used is to make fonts more standard, especially when you have a number of editors who tend to like there own font. You could then use this interception point to cycle through all the fonts and set them back to a standard font.

There are probably a lot more use case than just these two I mentioned, but I still fail to see what you are trying to do with your widgets after your views have been rendered and not when they are being rendered.

But this is post processing, that means for your widgets they would need to be controlled via a view and you would need to use your own interception point to then do what you need to do. If I am understanding you.

Maybe explain what you’re doing with an interception point and rendering with your widgets, but personally I would be looking at a custom interception point for your widgets that your module can deal with.

//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
public void function cb_onContentRendering(event, interceptData) {
var page = event.getValue(“page”, 1);
translateContent( builder = arguments.interceptData.builder, content = arguments.interceptData.content, page = page);
}

private function translateContent11(required builder, content, page){

var regex = “(@@PageBreak@@)”;
var pattern = createObject(“java”, “java.util.regex.Pattern”);
var matcher = pattern.compile(regex).matcher(builder.toString());
var pageCount = arrayLen( reMatch( regex, builder.toString() ) ) + 1;
var pages = [];
var buffer = createObject(“java”,“java.lang.StringBuilder”).init();

while(matcher.find()) {
var matchedString = matcher.group();
var loc = {start = matcher.start(), end = matcher.end()};
arrayAppend(pages, loc);
}

if( page > pageCount) {
page = 1;
}

if(arrayLen(pages) == 0) {
return;
}

if(page == 1) {
// Get page 1
buffer.append(left(builder.toString(), pages[page].start ));
} else if (page == pageCount) {
// Get Last page
buffer.append(right( builder.toString(), builder.length() - pages[page-1].end ));
} else {
// Get page middle content
var midStart = pages[page-1].end;
var midEnd = pages[page].start;
var midLength = midEnd - midStart;
buffer.append(mid( builder.toString(), midStart + 1, midLength ));
}

builder.replace(0, builder.length(), buffer.toString());
}

I’m talking about widget displayed on layout, not view.

On layout there are some interception point that I use to display my widget. This is a try to emulate what happens with wordpress, where you can insert widget on layout/theme without touching code.

It shouldn’t matter, the widget still needs something to render the information or output what the widget is displaying. So if you wanted to do anything pre/post on the widget, would you not use an interception point in that?

I also worked on this, but never got to finish it. I never did mine in the layout and it was an actual view. The view container took the information required to display the widgets and created view based on that information, I felt that putting the widgets in the actual layout was breaking encapsulation.

Ok I just looked at your code, I am confused what you’re talking about the CB_ContentRendering and what you’re doing in this interception point.

I think I will go and get some sleep, I don’t see another way. What you’re doing is what I did.

Thanks Andrew for your help.

If you want, you can try to install my module from forgebox. It does work, and displays correctly the widgets on layout.

I’m asking if there is a better way to accomplish this.

This is because on every request the interception point are fired, my interceptor looks for registered widgets on that interception point and render it.

I think that a better solution is to make this process one step left: I’d like to have a method to render widgets on first request, render widgets and cache them inside the page/layout, then all further requests will be served by a cached page/layout, without the needs to fire action on each interception oint.

I don’t know if there is a better way to explain this…

Yeah, that’s why I said I don’t think there is. I know when I did it I wasn’t using interception points like that. I was using the layout to display content that would mimic the layout of widgets and dynamically create it in one hit. It has been 6 years since I looked at doing this, but I thought doing it all in one hit was better.

But Wordpress has probably changed a lot since I last used it all those years ago too.