Jump to content
Macrura

Simple example for widget management

Recommended Posts

Some sites need widgets, as they have been called in some systems; a widget can be almost anything, like:

  • tag cloud
  • mini calendar
  • menu
  • quote rotator
  • free text
  • social sharing
  • search
  • contact info
  • map

This is a simple way to create widgets that can be shown in multiple "areas" of a page, as well as on specific pages.

In this particular method you would need to setup each widget type you want and then determine how best to accept any necessary user input like content, pages select (like for a menu) or settings.

This example uses include files for each widget type, and the name of the include file would match the name of the widget type, which is also a page field.

In this example, I'm also using ListerPro to provide a widget management page.

post-136-0-36099500-1419542584_thumb.png

Fields

The main fields used on this widget example are :

title

widget_location (page select - options in this case are footer and sidebar)

widget_type (page select, you would configure your widget types as selectable options)

pages_select (would be used for multiple pages and might apply to a menu widget)

body - used for plain widgets

selector (selector inputfield, used for telling the system where to show the widget)

text_structured - for this i'm using a YAML field, but it could just as easily be a table; would depend on what you want to store; YAML would allow this single field to be used for varying requirements based on the widget type, but would be harder to validate and prone to user error;

icon - a page select for an optional icon which is being used in the template, and would be shown as part of the widget.

post-136-0-09537600-1419542583_thumb.png

Files

for each widget type you want to allow users to select from, you would need to create an include file with the markup for that widget, and then add that widget to the list of available widgets.

here is an example for a site with several widget types:

post-136-0-64137500-1419542689_thumb.png

Selector & Output

wherever you want to include the widgets (footer, sidebar etc.) you would run a $pages->find and then foreach through the widgets (in this case finding all footer widgets).

In this case the (incredibly amazing new) selector field would be specifying what pages to show the widget on.

post-136-0-28663900-1419542582_thumb.png

We assume that most widgets won't have a selector specified, and will default to show the widget.

if a selector is specified, we can check to see if this page fits the selector by using the $page->is($selector) syntax.

<?php
$widgets = $pages->find("template=widget, widget_location=footer, sort=sort");
    
foreach($widgets as $widget) {
    
    // check if the selector field is in use and if so, see if this page is supposed to display it:
    if( $widget->selector) {
        if( !$page->is("$widget->selector") ) continue;
    }

    $widgetType = $widget->widget_type->name;    
    $include = file_exists("./inc/widget-{$widgetType}-foot.inc") ? "./inc/widget-{$widgetType}-foot.inc" : './inc/widget-footer.inc';
    include($include);
}
?>   

this example also has a fallback file in case the widget type is not specified, sort of a default.

the widget's .inc file will be unique to your design and how you have it setup.

  • Like 19

Share this post


Link to post
Share on other sites

In this case the (incredibly amazing new) selector field would be specifying what pages to show the widget on.

great writeup macrura! what do you mean by the incredibly amazing new selector field? :)

edit: oh - just saw what you meant on your screenshot and didn't see it before!!!  :huh: i thought you were talking about the page select field... where can i find more info on this?

--------------------------------------

here is my old posting - just for the record. it seems it is quite useless having the new selector field  :rolleyes:

edit: polished version here: https://processwire.com/talk/topic/8635-simple-example-for-widget-management/?p=95532

i also have a widget setup on one of my sites with a little different approach of how to manage visibility of the widgets (3rd column: if this box is checked, the rule applies also to its sub-pages)

post-2137-0-80114300-1419630850_thumb.pn

for every widget you can setup "display rules" including #page #include/exclude and #include_children. it's kind of a bottom-up approach: the example above would show the widget on all subpages of /games AND on page /games (rule #3), but would NOT show an page /games (rule #2 removes access given from #3) and would not show an any other page (home + subpages, rule #1).

a simpler example would be:

rule | page      |         | sub-pages?
------------------------------------------
#1   | home      | exclude | yes
#2   | /section1 | include | yes

so this widget would show on all pages in section1 (eg /section1, /section1/post-1, /section1/post-2 ...)

you could easily exclude the widget on page /section1/post-2 by adding

#3   | /section1/post-2 | exclude | no

...and it would still display an all other pages (posts) in section1, including newly added ones (post-3, post-4...).

if anyone is interested in the code i can share it with you - altough it's quite messy because it's only a prototype for now. i also have to say that i don't like the repeaters because they are wasting lot of space for displaying only 3 small pieces of information. maybe a pagetable field would be better for the next version...

i'm also managing this site on my own, so i have no experience with clients handling this display rules for now!

  • Like 2

Share this post


Link to post
Share on other sites

Hi BernhardB - awesome and thanks so much for joining in on this.. i really like your approach to the widgets also; 

edit: oh dear - just saw what you meant on your screenshot and didn't see it before!!!  :huh: i thought you were talking about the page select field... where can i find more info on this?

the InputfieldSelector field isn't that new, i can't remember when it was announced  - i think this past summer; but in terms of the CMS, it is pretty new and it was conceived by  Antti Peisa, coded by Ryan Cramer and sponsored by Avoine; it is in the core, so you just need to install it.

The field is used in the listers; as a standalone field i haven't seen many posts about day-to-day use of it and i kept thinking of when and where it might come in handy.. then while i was setting up this one site I came across this situation where i wanted a certain widget only to show up on the child pages of another page; so first i did a plain field and typed in the selector and sort of moved on... but something kept nagging at me and then it suddenly dawned on me that there is already this field that could make setting up the selector more user friendly and reliable, and it works great; It provides feedback to tell you how many pages match your selector;

for some clients who have a little technical knowledge and skill, this is a really simple and easy way to specify a selector for pages, and then be able to test against that selector in conditionals.. i think in some instances it is probably too technical to be of use;

i wonder if you could use the new selector field in your setup, as you can add additional lines to the selector, which would be like your repeaters... i haven't done extensive testing or experimenting yet with this, but i have 3 more sites to launch and i'm sure this selector field will get more use in situations like this..

  • Like 4

Share this post


Link to post
Share on other sites

@adrianmak,

the widget include file should contain all of the necessary markup to render the widget;

for example, here is a simple text widget, that is being used in a bootstrap based site:

<div class="col-md-4 bottommargin<?=$wClass?>">
    <?php echo $widget->body?>
    <?php if($widget->page_select) { ?>
    <a href="<?=$widget->page_select->url?>" class="more-link">Read More</a><? } ?>
    <div class="clear"></div>
</div>

here's another widget that is being used in a "call to action"

<?php
$image = $widget->images->first();
$image = $image->width(720);
$description = $image->description;
$markdown->format($description);
?>

<div class="col-md-4 bottommargin <?php echo $widget->widget_type->name?><?=$wClass?>">
    <div class="entry clearfix">
        
        <div class="entry-image">
            <?php if($widget->page_select) { ?><a href="<?=$widget->page_select->url?>"><?php } ?>
            <img src="<?=$image->url?>" class="image_fade" alt="<?=$widget->title?>">
            <?php if($widget->page_select) { ?></a><?php } ?>
            <div class="caption"><?php echo $description?></div>
        </div>
        
        <?php if($widget->page_select) { ?>
        <a href="<?=$widget->page_select->url?>" class="more-link">Read More</a><? } ?>
        
    </div>
</div>
  • Like 1

Share this post


Link to post
Share on other sites

Some sites need widgets, as they have been called in some systems; a widget can be almost anything, like:

  • tag cloud
  • mini calendar
  • menu
  • quote rotator
  • free text
  • social sharing
  • search
  • contact info
  • map

This is a simple way to create widgets that can be shown in multiple "areas" of a page, as well as on specific pages.

In this particular method you would need to setup each widget type you want and then determine how best to accept any necessary user input like content, pages select (like for a menu) or settings.

This example uses include files for each widget type, and the name of the include file would match the name of the widget type, which is also a page field.

In this example, I'm also using ListerPro to provide a widget management page.

attachicon.gifwidgets.png

Fields

The main fields used on this widget example are :

title

widget_location (page select - options in this case are footer and sidebar)

widget_type (page select, you would configure your widget types as selectable options)

pages_select (would be used for multiple pages and might apply to a menu widget)

body - used for plain widgets

selector (selector inputfield, used for telling the system where to show the widget)

text_structured - for this i'm using a YAML field, but it could just as easily be a table; would depend on what you want to store; YAML would allow this single field to be used for varying requirements based on the widget type, but would be harder to validate and prone to user error;

icon - a page select for an optional icon which is being used in the template, and would be shown as part of the widget.

attachicon.gifwidget_template.png

Files

for each widget type you want to allow users to select from, you would need to create an include file with the markup for that widget, and then add that widget to the list of available widgets.

here is an example for a site with several widget types:

attachicon.gifwidgets_inc.png

Selector & Output

wherever you want to include the widgets (footer, sidebar etc.) you would run a $pages->find and then foreach through the widgets (in this case finding all footer widgets).

In this case the (incredibly amazing new) selector field would be specifying what pages to show the widget on.

attachicon.gifpopup2.png

We assume that most widgets won't have a selector specified, and will default to show the widget.

if a selector is specified, we can check to see if this page fits the selector by using the $page->is($selector) syntax.

<?php
$widgets = $pages->find("template=widget, widget_location=footer, sort=sort");
    
foreach($widgets as $widget) {
    
    // check if the selector field is in use and if so, see if this page is supposed to display it:
    if( $widget->selector) {
        if( !$page->is("$widget->selector") ) continue;
    }

    $widgetType = $widget->widget_type->name;    
    $include = file_exists("./inc/widget-{$widgetType}-foot.inc") ? "./inc/widget-{$widgetType}-foot.inc" : './inc/widget-footer.inc';
    include($include);
}
?>   

this example also has a fallback file in case the widget type is not specified, sort of a default.

the widget's .inc file will be unique to your design and how you have it setup.

without using the ListerPro paid module, how could i build such a management interface ?

Share this post


Link to post
Share on other sites

could be done super easy/fast - you would probably use admin custom pages and then build your table that returns the list of widgets and the various columns;

i think there may be a core inputfield for the table, or you roll your own data tables; admin custom files lets you load any js/css you need;

Share this post


Link to post
Share on other sites

It took me some time to find how to use Selector Inputfield, so I think this post just might help someone else.

As it should be obvious from the word Inputfield (was not for me :)) it is not a fieldtype. That means you should create a field with fieldtype "Page" and then select "Selector" inputfield on the "Input" tab. But it can't be done without some customization. You need to go to the Inputfield Page module config in Modules and add it to the allowed inputfield list. After that all works as expected.

Thank you, Macrura! Without you topic I wouldn't even know this awesome inputfield existed in the first place.

  • Like 2

Share this post


Link to post
Share on other sites

AFAIK this is not true; you can just create a field and use type Selector from the dropdown; there shouldn't be any extra steps needed.

@Ivan Gretsky - maybe you didn't install the module?

  • Like 1

Share this post


Link to post
Share on other sites

I am converting a Joomla/Seblod install and in that process developed a widget system quite similar to Marcrura's. In Joomla widgets are called modules and in that particular install those modules were used quite a lot.

To render modules (widgets) in Joomla you do something like

<?php if ($this->countModules('content_bottom')): ?>
<div class="content_bottom">
	<jdoc:include type="modules" name="content_bottom" style="inner" />
</div>
<?php endif; ?>

So I tried to find a way in PW to conditionally output widgets.

In my widget template, I have widget positions and layouts as page fields, just like Marcrura shows. Plus a page field of type PageListSelectMultiple to determine on which pages to show the widget. And, like Berhard, I have a checkbox to determine whether to show the widget also on child pages.

Instead of using includes for each widget position, I use switch case statements in my widget template

// get layout
$layout = $page->layout->name;

// layouts
switch ($layout) {
    case 'carousel':

      // code to render carousel markup
      echo $carousel;

      break;

    case 'teaser':

      // code to render teaser markup

      echo $teaser;

      break;
    // ... etc.

I use the delegate template approach like in the default site template with an _init.php that gets prepended and a _main.php that gets appended and outputs variables that are being populated in the page templates.

Here is the logic to render widgets in the main content area of my _main.php

<main class="col-sm-<?php echo $contentwidth; ?> content equalHeight">
  <?php if($above) { ?> <!-- widget position above -->
  <div class="above">
    <?php echo $above; ?>
  </div>
  <?php } ?>

  <?php echo $content; ?>

  <?php if($below) { ?> <!-- widget position below -->
  <div class="row below">
    <?php echo $below; ?>
  </div>
  <?php } ?>
</main>

$above and $below hold the markup for all widgets in that position on that page and are false if there are none.

And this is the code I use to determine whether there are widgets in that particular position on that particular page.

In my _init.php I first set all position variables ($above, $below etc.) to false. (module translates to widget here)

// Set all module variables to false

foreach ($pages->find('template=modulepositions_items') as $position) {
  ${$position->name} = false;
}

The widget position pages all have the template modulepositions_items. So I iterate through all positions and then use Variable variables to create the position variables ($above, $below etc.) and set them to false.

This step is needed to avoid PHP "Undefined Variable" notices.

In my _main.php I store the widget markup in the position variables before all the other template markup (again module translates to widget)

// get modules
$modules = $pages->find('template=module, sort=sort');

// render modules in their positions
foreach ($modules as $module) {
    // if module is assigned to this page or it's parent, render it on it's position
  if (count($module->onpages) == 0) { // if no specific pages are assigned, render module on all pages
    ${$module->moduleposition->name} .= $module->render();
  } elseif ($module->include_children  == 1 ) {
   if ($module->onpages->has($page) || $module->onpages->has($page->parent('id!=1'))) ${$module->moduleposition->name} .= $module->render();
  } elseif ($module->include_children == 0 && $module->onpages->has($page)) {
   ${$module->moduleposition->name} .= $module->render();
  }
}

Lets brake this down:

"onpages" is the page field in my widget template that determines on which pages to show the widget.

${$module->moduleposition->name} .= $module->render(); renders the markup $module->render() of the widget and adds it to the position variable ${$module->moduleposition->name} which again is a variable variable (just like that expression too much ;) )

The if and elseif statements  check whether the widget should be rendered on that particular page. They feel a bit clumsy and I think I will change my setup to using the selector field instead.

To summarize: with this method you get a quite flexible widget system with the benefit of minimizing the code used to render them in _main.php and the possibility to have conditional markup depending on whether there are widgets for that position or not.

Thank you guys for sharing your approaches which gives me some good ideas for improving on my own.

  • Like 3

Share this post


Link to post
Share on other sites

@gebeer - many thanks for your time in sharing your technique - as a former Joomla(er?) also, i appreciate your approach to the modular widgets.. i'll surely study your example when i have another scenario like this...

Share this post


Link to post
Share on other sites

Many thanks for sharing this example.

I've implemented this on my website, but i'm kinda stuck now. I've created an if statement to check if there are 0, 1 or 2 sidebars. With this if statement i'm changing the class on my body element so I can correctly style the page to display these sidebars.

This is working till I set the 'selector' for a specific widget. If I set a widget to be displayed e.g. only on the homepage, the widget is displayed correctly. However on all the other pages, the class still prints out as if there is 1 sidebar.

I've added my if statement below:

$sidebar_left = $pages->find("template=widget, widget_location.value=left");
$sidebar_right = $pages->find("template=widget, widget_location.value=right");

if(count($sidebar_right) > 0 && count($sidebar_left) > 0) {
    $body_class = "two-columns";
} elseif(count($sidebar_right) > 0) {
    $body_class = "sidebar-right";
} elseif(count($sidebar_left) > 0) {
    $body_class = "sidebar-left";
} else {
    $body_class = "one-column";
}

I've tried different versions, but those don't seem to work:

find("template=widget, widget_location.value=left, selector!=")
find("template=widget, widget_location.value=left, selector!=0")
find("template=widget, widget_location.value=left, selector<0")

Is there a way to check inside the find() method if the selector field is set or is there perhaps a better way to set the body class?

Share this post


Link to post
Share on other sites

you may need to make a pagearray, it's hard to tell because i can't see where/how you're excluding widgets by selector.

my example runs a 'negative' $page->is($selector) over the found items - i would assume you actually want to find all items that don't have the selector set:

Share this post


Link to post
Share on other sites

@Macrura, thanks for your reply.

I've tried multiple setups today, but unfortunately I can't seem to get it working. Ideally the body_class and the if statement for sidebars are adjusted based on the selector field.

I currently have the following code inside my _main.php file.

If statement at the top of the page to check if there is widget for sidebar left or sidebar right:

$sidebar_left = $pages->find("template=widget, widget_location.value=left");
$sidebar_right = $pages->find("template=widget, widget_location.value=right");

if(count($sidebar_right) > 0 && count($sidebar_left) > 0) {
    $body_class = "two-columns";
} elseif(count($sidebar_right) > 0) {
    $body_class = "sidebar-right";
} elseif(count($sidebar_left) > 0) {
    $body_class = "sidebar-left";
} else {
    $body_class = "one-column";
}

Setting the body class

<body class="<?php echo $body_class; ?>">

Sidebar Left

<?php if(count($sidebar_left)): ?>
    <aside class="sidebar-left">
        <?php

            foreach($sidebar_left as $widget) {

                // check if the selector field is in use and if so, see if this page is supposed to display it:
                if( $widget->selector) {
                    if( !$page->is("$widget->selector") ) continue;
                }

                $widgetType = $widget->widget_type->value;
                $widgetTemplate = file_exists("./partials/widget_{$widgetType}.php") ? "./partials/widget_{$widgetType}.php" : "./partials/widget_next_race.php";
                include($widgetTemplate);
                echo $page->is("$widget->selector");
                echo $widget->selector;
            }

          ?>
    </aside>
<?php endif; ?>

And Sidebar Right

<?php if(count($sidebar_right)): ?>
    <aside class="sidebar-right">
        <?php

            foreach($sidebar_right as $widget) {

                // check if the selector field is in use and if so, see if this page is supposed to display it:
                if( $widget->selector) {
                    if( !$page->is("$widget->selector") ) continue;
                }

                $widgetType = $widget->widget_type->value;
                $widgetTemplate = file_exists("./partials/widget_{$widgetType}.php") ? "./partials/widget_{$widgetType}.php" : "./partials/widget_next_race.php";
                include($widgetTemplate);
                echo $page->is("$widget->selector");
                echo $widget->selector;
            }

          ?>
    </aside>
<?php endif; ?>

Share this post


Link to post
Share on other sites

you'd probably need to redo this logic;

1.) maybe consider an array for your body classes which you an unset keys for based on some conditions

2.) you should not be rendering the sidebar at all if there are no widgets, which means that you need to check your widget counts for each area before _main;

that's why you probably need to do a pagearray or something; it's too late to check the selector once you are already looping, unless you can at that point you can unset/set the necessary array key for the body class;

this can be resolved but the logic needs to be adjusted because as of now you are assuming there is always something in the sidebars;

when i did my example, it was on a template that always had a sidebar no matter what, so i was able to safely foreach those addon widgets; but again, in your case you need to collate your widgets for each respective part of the page before you output any markup so that your body classes can be correct

Share this post


Link to post
Share on other sites

Thanks for the additional information, that helped me a lot in finding a solution. I will post the code below that i'm using for anyone that might want to achieve the same behavior:

If statement at top of _main.php

$sidebar_left = $pages->find("template=widget, widget_location.value=left");
$sidebar_left_count = 0;
foreach($sidebar_left as $widgets) {
  if($page->is("$widgets->selector")) {
    $sidebar_left_count++;
  }
}

$sidebar_right = $pages->find("template=widget, widget_location.value=right");
$sidebar_right_count = 0;
foreach($sidebar_right as $widgets) {
  if($page->is("$widgets->selector")) {
    $sidebar_right_count++;
  }
}

if($sidebar_right_count > 0 && $sidebar_left_count > 0) {
    $body_class = "two-columns";
} elseif($sidebar_right_count > 0) {
    $body_class = "sidebar-right";
} elseif($sidebar_left_count > 0) {
    $body_class = "sidebar-left";
} else {
    $body_class = "one-column";
}

Set the class on the body element

<body class="<?php echo $body_class; ?>">

Sidebar Left

<?php if($sidebar_left_count > 0): ?>
    <aside class="sidebar-left">
        <?php

            foreach($sidebar_left as $widget) {

                // check if the selector field is in use and if so, see if this page is supposed to display it:
                if( $widget->selector) {
                    if( !$page->is("$widget->selector") ) continue;
                }

                $widgetType = $widget->widget_type->value;
                $widgetTemplate = file_exists("./partials/widget_{$widgetType}.php") ? "./partials/widget_{$widgetType}.php" : "./partials/widget_next_race.php";
                include($widgetTemplate);
            }

          ?>
    </aside>
<?php endif; ?>

Sidebar Right

<?php if($sidebar_right_count > 0): ?>
    <aside class="sidebar-right">
        <?php

            foreach($sidebar_right as $widget) {

                // check if the selector field is in use and if so, see if this page is supposed to display it:
                if( $widget->selector) {
                    if( !$page->is("$widget->selector") ) continue;
                }

                $widgetType = $widget->widget_type->value;
                $widgetTemplate = file_exists("./partials/widget_{$widgetType}.php") ? "./partials/widget_{$widgetType}.php" : "./partials/widget_next_race.php";
                include($widgetTemplate);
            }

          ?>
    </aside>
<?php endif; ?>
  • Like 1

Share this post


Link to post
Share on other sites

just wanted to share a screencast of one old website with a kind of widget-visibility-ui that could serve as inspiration.

it's not good enough to share as a module, maybe someone wants to take it further -> pm :)

widget.thumb.gif.ecc2d942a361fe9884823d75bf888346.gif

  • Like 3

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Mike Rockett
      Docs & Download: rockettpw/markup-sitemap
      Modules Directory: MarkupSitemap
      Composer: rockett/sitemap
      MarkupSitemap is essentially an upgrade to MarkupSitemapXML by Pete. It adds multi-language support using the built-in LanguageSupportPageNames. Where multi-language pages are available, they are added to the sitemap by means of an alternate link in that page's <url>. Support for listing images in the sitemap on a page-by-page basis and using a sitemap stylesheet are also added.
      Example when using the built-in multi-language profile:
      <url> <loc>http://domain.local/about/</loc> <lastmod>2017-08-27T16:16:32+02:00</lastmod> <xhtml:link rel="alternate" hreflang="en" href="http://domain.local/en/about/"/> <xhtml:link rel="alternate" hreflang="de" href="http://domain.local/de/uber/"/> <xhtml:link rel="alternate" hreflang="fi" href="http://domain.local/fi/tietoja/"/> </url> It also uses a locally maintained fork of a sitemap package by Matthew Davies that assists in automating the process.
      The doesn't use the same sitemap_ignore field available in MarkupSitemapXML. Rather, it renders sitemap options fields in a Page's Settings tab. One of the fields is for excluding a Page from the sitemap, and another is for excluding its children. You can assign which templates get these config fields in the module's configuration (much like you would with MarkupSEO).
      Note that the two exclusion options are mutually exclusive at this point as there may be cases where you don't want to show a parent page, but only its children. Whilst unorthodox, I'm leaving the flexibility there. (The home page cannot be excluded from the sitemap, so the applicable exclusion fields won't be available there.)
      As of December 2017, you can also exclude templates from sitemap access altogether, whilst retaining their settings if previously configured.
      Sitemap also allows you to include images for each page at the template level, and you can disable image output at the page level.
      The module allows you to set the priority on a per-page basis (it's optional and will not be included if not set).
      Lastly, a stylesheet option has also been added. You can use the default one (enabled by default), or set your own.
      Note that if the module is uninstalled, any saved data on a per-page basis is removed. The same thing happens for a specific page when it is deleted after having been trashed.
          
    • By MilenKo
      Hey everyone. I am at a stage of code cleaning for my first PW profile where I decided to implement some sidebar widget logic that would allow me to remove code repetition. I read about a few widget logic approaches that were working fine but that seemed too complicated for my needs so decided to implement something really simple that would do just that - widget logic that can be changed through the admin but not through code editing.
      So before I share my idea, I would give you some info of the structures I have:
      -- Recipes
      ---- Child 1
      ---- Child 2
      -- Ingredients
      ---- Child 1
      ---- Child 2
       
      So in my project needs, I wanted to have a solution that would allow me to set through the profile admin one or group of widgets per template (it would allow unlimited widgets as far as I have the code for it).
      So to achieve this functionality, I took the following steps:
      1. Create a template, called widget_logic and set the allowed template for children to be itself (widget_logic)
      2. Create a page Site Widgets and assign to it the widget_logic template.
      3. Create a field called listing_widgets and set its type to Page Reference.
      4. In Details tab select Multiple Page Array to allow multiple widgets to be selected.
      5. In the input tab chose Page Auto Complete as input field type.
      6. In Selectable pages point the parent to your widgets page name (Site Widgets in this example) and set the widgets_logic as the template.
      7. Repeat the steps 3-6 creating another field: inner_widgets (this would allow you to have different widgets per listing template and inner page )
      7. Add manually the child pages with the widgets names in Site Widgets page you just created.
      8. Assign the fields to the parent templates that you want the widgets to be pulled from (in this case: Recipes, Blog etc.)
      9. In the template code, pull the page parent through API using the loop you use to list the results in the page. For this tutorial I will set the widgets to Recipes template that shows a listing of all the recipes matching my criterias:
      //Build a selector and limit page results to 5 $result = $page->children("limit=5, sort=-published"); //Pull the parent of the first child-page to be used for widget logic $parent = $result->first()->parent(); 10. Once we know the parent and we know the field names assigned to it containing the widgets, we use a simple loop in each template to get the selected widgets name and include them where needed. Note, for the widgets naming I used: widget-XXX-YYY.php (eg. widget-recipe-top.php). If you prefer other naming, make sure you change the include line to match the new names.
      //Loop through all the widgets setup in the parent template foreach ($parent->listing_widgets as $w) {     //Including all the widgets by file name and order set in the parent widgets field     include ('./includes/widget-' . $w->title . '.php'); 11. In the Recipe-inner template I would do the same:
      $parent = $page->parent(); //Loop through all the widgets setup in the parent template foreach ($parent->inner_widgets as $w) {     //Including all the widgets by file name and order set in the parent widgets field     include ('./includes/widget-' . $w->title . '.php'); } NOTE: in the inner page template I changed the field name to inner_widgets to pull the widgets for the inner page.
      12. Now all that is left is to assign the two fields to every parent and/or inner page template that you would like to use the simple widget logic and select the widgets for each one.

      It might not be the best approach, however it is super simple to setup and allows me to have different widgets on any template now. The variety of widgets could be extended at any time by just adding the new widget, create the page with the name for it and assign it to the chosen template. Having the Page Auto Select field would allow you to drag and drop the widgets to reorder them so it suited my needs perfectly. Hope it would for you as well. Any code improvements are more than welcome (as usual
      P.S. On the image of widgets view, I set the size of both fields to be 50% so that they show up on the same line and save the space and scrolling.

    • By fabjeck
      Hi all, I am new to PW and building up a website for a customer and have some problems with structuring my project:
      On my main.php file I have a main-tag where I wan't to echo the region called 'content'. But the problem is that the markup inside this wrapper should be variable.Example: I have a page where all the news previews are outputed  like in a normal news app--> no additional markup is needed. But on "home" I want to have different sections with content -->
       
      <section>     <div class="slider">         <!--here i want to have some filtered news articles-->     </div> </section> <section> <div class="news">         <!--here i want to have some news articles but with another filter-->     </div> </section>

      How can I realise that? It has to be like that for responsive purposes. 
      Is it maybe possible to create and echo regions inside the "parent region"?

      Cheers and thank you for your help
       
    • By mr-fan
      Just working on some smaller projects and take the step into the actual master/dev version and all the new methods and api chunks that are coming with the 3.x series...
      since i'm not always build websites i'm not always go with the brand new things and put them in my workflow....there is a 24 per day timelimit i think...;)
      BUT actual i dive deep in markup regions....and holy shit this feature ROCKS!
      It should put in place better than in some blogposts:
      http://processwire.com/blog/posts/processwire-3.0.49-introduces-a-new-template-file-strategy/
      http://processwire.com/blog/posts/processwire-3.0.62-and-more-on-markup-regions/
      or can some admins make a headline in the official docs and link to the blogentries??
      This feature is to important to get missed for beginners and other users of PW!
      I'm just kick my whole workflow and change it for the markup regions....i'm feeling like xmas in summer Thank you @ryan
      Best regards and happy "new" year....
    • By MilenKo
      Hello. I am working on a culinary web project where I am aiming at listing all recipes with a pagination after reaching the recipe limit. As far as I already did the pagination on another project, I was quite happy to use the code and see it in action. However, my joy was not lasting long as far as the present pagination HTML code differs from the other and I was scratching my head today for several hours and yet no solution to precisely match the styling.
      I was able to apply the pagination, show the prev/next and numbers properly, however the active class is not applied properly and the design has the prev/next arrows at the both ends of the recipe block (image attached).
      Here is the pagination original html code:
      <!-- Pagination --> <div class="sixteen columns"> <div class="pagination-container"> <nav class="pagination"> <ul> <li><a href="#" class="current-page">1</a></li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> </ul> </nav> <nav class="pagination-next-prev"> <ul> <li><a href="#" class="prev"></a></li> <li><a href="#" class="next"></a></li> </ul> </nav> </div> </div> And here is my pagination code (after making sure that the template pagination is enabled):
      <div class="sixteen columns"> <div class="pagination-container"> <?php echo $result->renderPager(array( "nextItemLabel" => __(">>"), "previousItemLabel" => __("<<"), "currentItemClass" => "current-page", 'listMarkup' => "<nav class='pagination'><ul>{out}</ul></nav>", 'itemMarkup' => "<li>{out}</li>", 'linkMarkup' => "<a href='{url}'>{out}</a>" )); ?> <nav class="pagination-next-prev"> <ul> <li><a href="#" class="prev"></a></li> <li><a href="#" class="next"></a></li> </ul> </nav> </div> </div> As far as the pagination active class is not applied on the <li> but on the <a href... > I tried to change the linkMarkup to: 'linkMarkup' => "<a href='{url}' class='{class}'>{out}</a>" however that shows that the {class} is not applied with linkMarkup but with itemMarkup. Tried to add the class to itemMarkup too, but the same result is showing.
      For sure the navigation is not an issue if it is next to the numbers, however I wanted to attempt to match fully the style and learn how can I move the prev and next pointers away from there or in other words to match the original theme.
      So any ideas how to achieve the proper functionality and obtain the previous/next page links? I read so many tutorials and manuals today mentioning to use prev() and next() but in my case the results are not coming from $page and the next page pointed to the next page in my admin but not the next results page.

×
×
  • Create New...