Jump to content

Widgets and page field


OLSA
 Share

Recommended Posts

Hello for all,

I try to find solution for my problem but without success.

I want to create selectable "widgets" option (banners) inside pages, and for that try to use Ryan "Blogprofile" principle:

1. create page widgets (hidden) with blank ("no file") template

2. inside page Widgets, child pages are different type of content (image+link, text box with some link, link lists etc...)

3. every "banner" has it's own template with markup

Inside Home page I created page field type (asmSelect) and set that selectable parent template is "widgets". 

And all that works, no any problems with administration - I can select desired widget/banner.

Because some desired eg. "Home" page doesn't know what kind of content is some widget (image+link, or text box with link, some list etc...) I use this in _main.php

// _main.php

$widgets = $page->widgets;
if(!$widgets || !count($widgets)) $widgets = $homepage->widgets;
foreach($widgets as $widget) {
  echo $widget->render(); // echo $widget shows correct ID
}

And some "banner" inside banner template has this (example):

// banner.php

$out = "<h4>{$page->title}</h4>";
echo $out;

But I have problem that page (website) not load?

Inside errors log ("site/assets/logs") I don't have any problem, everything is clean.

My opinion is that I don't use correctly render() method??? My template structure is like latest PW (2.5.3) multilanguage profile.

Thanks for any help.

Link to comment
Share on other sites

@Macrura thanks for answer,

but Yes I have template file for every widget type (eg. banner.php), and parrent page (Widgets) use template but without file (just like Widgets inside "Blogprofile").

Link to comment
Share on other sites

I get totally strange behavior with website loading, and at some moments I get this error inside error. log:

"Maximum function nesting level of '100' reached, aborting! (line 733 of ......wire\core\Page.php)"

I tried to change limit to 200, and also disable xdebug, but that didn't solve my problem.

I will try to find some different approach to get selectable widgets inside pages/templates (try to avoid render() method).

Thanks. 

Link to comment
Share on other sites

As Macrura pointed out,

1. create page widgets (hidden) with blank ("no file") template

seems to indicate that you have not linked the widget template with the banner.php file. When using $widget->render(), Processwire will check the template of the $widget Page object (I assume it's the widget template), and use its template file to render. If it doesn't have any (i.e. if you didn't set a template file), it will simply return an empty string. What you would need to do is manually set the template file to use for rendering like this:

// Assumes that "banner.php" is in the /site/templates folder
$widget->render($config->paths->templates . "banner.php");

But I think that the better way to do this is as follows:

  • Create a widgets-catalog template with no template file, but with access restrictions to prevent anyone from viewing directly this page and its children. Then create a "Widgets catalog" page. This will be the parent page for all your different widgets, whatever their type.
  • Create different templates for different widget types (e.g., text-banner, image-banner, etc.) which each have the relevant fields (file + link fields for the image-banner, text + link fields for the text-banner, etc.). Each of these templates has a corresponding template file in the /site/templates folder.
  • Create a widgets page field, with selectable pages set to having "Widgets catalog" as the parent page.
  • Add the widgets field to the home page and any other pages that you want.

Now you can select any widget type with the widgets field, and use $widget->render(), which will use the correct template to render.

Link to comment
Share on other sites

But I think that the better way to do this is as follows:
  • Create a widgets-catalog template with no template file, but with access restrictions to prevent anyone from viewing directly this page and its children. Then create a "Widgets catalog" page. This will be the parent page for all your different widgets, whatever their type.
  • Create different templates for different widget types (e.g., text-banner, image-banner, etc.) which each have the relevant fields (file + link fields for the image-banner, text + link fields for the text-banner, etc.). Each of these templates has a corresponding template file in the /site/templates folder.
  • Create a widgets page field, with selectable pages set to having "Widgets catalog" as the parent page.
  • Add the widgets field to the home page and any other pages that you want.

Now you can select any widget type with the widgets field, and use $widget->render(), which will use the correct template to render.

Yes, that is what I done, sorry if I was not clear enough in my first post.

Link to comment
Share on other sites

The maximum function nesting thing reeks of recursion. Maybe one of your widgets tries to render itself or some other page that also has this widget? Perhaps inside a prepended/appended file? Is _main.inc auto-appended?

Yes and thanks for this, because that's help me.

What I want is that widgets (partials) need to be last in processing - and - widget can be any kind of content type (template).

Also, I know that all this can be done using some checks (function) and with known path to some partial (eg. $config->paths->templates . "banner.php" ) - but I want flexible principle inside main layout template file, and use at least possible logic for that job (later some new partials can be easily added to some new pages - without coding).

And @ Jan Romer, in my case _main.php is appended, and because I neglected that very important part - I get website loading problem. 

Finally I solve my problem when added 'appendFile'=>null to render() options.

// _main.php
// main layout template file
// appended

$widgets = $page->widgets;
if(!$widgets || !count($widgets)) $widgets = $homepage->widgets;
foreach($widgets as $widget) {
  echo $widget->render('', ['appendFile'=>null]); //'appendFile'=>null
}

With this I get desired result, very simple can add different content type widgets (partials, banners) to different pages.

Best regards and thanks!

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...