nickngqs

Creating dynamic blocks on a per page basis

Recommended Posts

Hi guys,

I'm trying to wrap my head around creating dynamic blocks where the end-user can add blocks on the fly on individual pages without specifying it in the templates.

What approach do you guys usually do? I've tried scouring the forum for solutions but seems to get abit confusing. I've read Hanna Code, Repeater Matrix, PagesTables and seen the youtube tutorials. Not sure, where to start from. I only got very minimal knowledge of php as I came from a front-end background (html, css, js)

I'm looking to define my blocks somewhere where the end-user will not be able to see.

For example, a simple block container

<div class='container'>
<div class='container__title'> {{ $title-field }} </div>
<div class='container__image'> {{ $image-field }} </div>
</div>


Then maybe we got a second block container

<div class='container-2'>
<div class='container-2__title'> {{ $title-field }} </div>
<div class='container-2__image'> {{ $image-field }} </div>
</div>


Then the end-user can just to add these blocks into any pages on the fly and re order them according to their needs. My processwire is v3 using the UIKit3 Admin if that makes any difference

Sorry if I sounded too noob.

Share this post


Link to post
Share on other sites
1 hour ago, abdus said:

Thanks @abdus for those links, I didn't knew they exist!

Good articles @Michael van Laar, please keep going on the series!

  • Like 1

Share this post


Link to post
Share on other sites

This is something that I've been trying to figure out for quite awhile. At the moment I do this:

1) Create template banner-index
2) Create template banner-entry
3) Create page 'Banners' using banner-index template
4) Create child page of whatever the banner will be, let's say 'Sounds good'.

So you now have:

1.png.e6f1c7b6cece178a5d694ca818652cc9.png

... and the template for 'Sounds good':

2.thumb.png.df3322e0599d99776481759ab02efc44.png

(link to page is a Page type which enables me to pick ANY page on the site with a PageListSelect+ as input field type and 'Home' set as parent)

So I create a file which is going to output the actual banner:

// includes/_banner.php
<?php namespace ProcessWire;
    // get the banner page determined by the id passed to this template
    // from wireIncludeFile additional array, see next snippet
    $banner = $pages->get($Id);
?>

<div class="jumbotron jumbotron-fluid py-6 text-center bg-repeat">
    <div class="container">
        <h2 class="display-4"><?= $banner->headingMain; ?></h2>
        <p class="lead"><?= $banner->headingSubtitle; ?></p>
        <a href='<?= $banner->linkToInternalPage->url; ?>' class='btn btn-primary'>Go to <?= $banner->linkToInternalPage->title; ?></a>
    </div>
</div>

...then I grab this file using 'wireIncludeFile' so I can pass an additional value into this template which is the id of the page:

// views/about.php
<?php wireIncludeFile('./includes/_banner', array('Id' => 1212)); ?>

So the page id of 'Sounds good' is '1212'. I pass this manually at the moment.

So now, when /about/ is viewed, it displays '_banner.php' wherever I want, where you can see the PHP is populated with values from the 'Sounds good' page:

3.thumb.png.7cb8b0686ac47feab5f7f969e504b241.png

So, what about making this a bit more dynamic instead of manual IDs in a template.

Create a new field 'bannerToDisplay' as a 'Page' field type:

4.thumb.png.a7d9e25e096889c1faef06a268340704.png

...then select it to return just a single page:

5.thumb.png.88dc472f136bef5f27140759dafcf604.png

...and choose the parent of selectable pages to be the 'Banners' page you made earlier using the 'banners-index' template with an input field type of 'Select':

6.thumb.png.5199b614caee70a7110ddf828a8fe77c.png

...go add this bad boy to a template!

7.thumb.png.e5361c0cc45f1608e601554201a4cb6b.png

...then go edit your page:

8.thumb.png.978155967e7f69b380b0a240deb8ef44.png

...choose a banner, save it. Go edit the code which renders '_banners.php' and get rid of that manual ID:

// views/about.php
<?php
     // if something has been selected from the 'Choose a banner' dropdown
    if ($page->bannerToDisplay) {
        // get the ID of the selected page
        $bannerPageId = $page->bannerToDisplay->id;
        // pass this ID to the _banner.php template
        wireIncludeFile('./includes/_banner', array('Id' => $bannerPageId));
    }
?>

...create another banner and then change the dropdown and refresh the page!

10.thumb.png.0031b8c14d1ac7a561f726f303f99df7.png

This is obviously just an example which enables adding of a single block but once you get the idea of the Page field type and how you could use it, your options will increase a fair bit.

The thing I found with repeaters is that you still can't add a content block above, say , a body field, then another one below it. Your template would literally just have to have the repeater on it and you add item after item. Of course, with a repeater, every item will be the same (defined once, then just repeated with alternative content in the same field types).

I'm going to try the pro fields repeater matrix next for something similar. I'd love to be able to make entire pages simply from blocks and to be able to drag them around. It takes a fair bit of forethought though. Just experiment, have fun!

NOTE: This still means you have to define WHERE the banner will go on the page via a template, but you can change WHICH banner to display on the page edit inside admin :) it doesn't solve your problem but hopefully helps a bit and gets you on your way. Good luck!

  • Like 3

Share this post


Link to post
Share on other sites

I have used Repeater Matrix for this purpose, to create a type of page builder, each repeater type being a possible section, though you still have to have a predefined set of repeater types, most of this types have a checkbox or two for customization of behaviour (even repeaters inside, works wonderful)

 59a7245f9d7f9_ScreenShot2017-08-30at3_46_23PM.thumb.png.3d4e93313940830ce8cea987891a4f37.png

 

  • Like 3

Share this post


Link to post
Share on other sites
21 minutes ago, elabx said:

I have used Repeater Matrix for this purpose, to create a type of page builder, each repeater type being a possible section, though you still have to have a predefined set of repeater types, most of this types have a checkbox or two for customization of behaviour (even repeaters inside, works wonderful)

 59a7245f9d7f9_ScreenShot2017-08-30at3_46_23PM.thumb.png.3d4e93313940830ce8cea987891a4f37.png

 

Nice. I like this approach, I tried similar but failed a while back, just couldn't get the desired HTML output. Will give it another shot with repeater matrix.

Share this post


Link to post
Share on other sites

@elabx, I know this is an older post (by a couple months), but how to you set up your template to handle if a user moves a section around (ie, moves the feature card above the intro)? 

Share this post


Link to post
Share on other sites

@louisstephens  Those content sections are just rendered with a foreach loop like:

foreach($page->test_matrix as $item) {
  if($item->type == 'blockquote') {
    echo "
      <blockquote>
         <p>$item->quote</p>
         <cite>$item->quote_cite</cite>
      </blockquote>
      ";
  } else if($item->type == 'bodycopy') {
    echo "
      <h2>$item->title</h2>
      $item->body
      ";
  } else if($item->type == 'gallery') {
    // and so on...
  }
}

That code was taken from http://processwire.com/api/modules/profields/repeater-matrix/

So when a user changes the order, it will automatically be displayed in that order on the frontend.

  • Like 1

Share this post


Link to post
Share on other sites

Thanks @gmclelland, I had the "how", but I guess I was confusing myself on how the rendering would actually work. I was just assuming that they would display in the order of the if statements and not the  way they were ordered. Ill go to my dev environment and test it all out. I appreciate the insight!

Share this post


Link to post
Share on other sites
17 hours ago, louisstephens said:

@elabx, I know this is an older post (by a couple months), but how to you set up your template to handle if a user moves a section around (ie, moves the feature card above the intro)? 

Just to give another opinion from @gmclelland , I organize the templates the following way:

site/templates/fields/{name of the repeater matrix field}/{name of the rep. matrix type}

e.g.

Assuming a repeater matrix field called "content" with a type called "slider":

site/templates/fields/content/slider.php

So I rather end up with several files instead of rendering in the main template, one per matrix type. Then, on the template which has the repeater matrix field:

content$page->render("content")

 

  • Like 1

Share this post


Link to post
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


  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By mikeuk
      (apologies if this looks too similar to previous topic I created, seems more logical as a new topic)
      I'm curious if anyone here is implementing something along the lines of Drupal's block / Joomla's custom (editable) module functionality?
      In other words, areas that are editable in the backend, that can be placed on multiple pages without needing to re-enter the content on each page it is used.
      I tried to do this using a page as a block, and then field type Page (to get a page within a page), but this led to issues with rendering, and more important this creates an object $page->fieldtypePage which is exceptionally large, so I would prefer to avoid that route.
      My guess is those that do it, do it outside of PW with PHP. But the 'blocks' being editable and creatable by a site editor is important so I need to explore this or find a different solution (or tell the client no-can-do).
    • By DarsVaeda
      Hi,
      I have the following simplified layout on my page:
      ...
      row1_card1 - row1_card2 - row1_card3
      row2_card1 - row2_card2 - row2_card3
      ...
      You can add as many rows and cards per row as you like. Each card has a title, text and a button whose text is the same on every card but should be editable too, just not individually.
      I wonder what is the best approach to do this without making it awfully complicated to setup in the admin from an editors perspective.
      I thought about a solution using a PageTable for the rows and a Repeater for the cards but that started to be complicated to setup even.
      It would be awesome if you could use the FrontpageEditing to edit these cards and even add more or add rows.
      How would you implement it?
    • By mrjasongorman
      I'm just wondering if there a way of creating block like functionality similar to say Episerver / drupal blocks??
      I guess i could treat the template as a view that loads in sever partials (kinda like blocks) ??
      Any ideas on this would be great.
    • By mrkhan
      Hello,
      i am trying to build one Page in CMS for menu Building.
      i have created a field name "menu_page" Page type & one text filed name "depth"
      now i have crated a new repeater name "menus" with above both fields.
      menus (repeater)                              menu_page (page type, single page)                              depth (text) now i add it one page name "header" and added values as bellow
      menus1              menu_page "about us" depth (0) menus2              menu_page "About Company" depth (1) menus3              menu_page "Products" depth (3) menus4              menu_page "Contact Us" depth (0) in my template file i have code as bellow
      <ul> <?php $menus=$pages->get("/header/"); foreach($menus as $menu) { ?> <li><a href="<?php echo $menu->url;?>"><?php echo $menu->title;?></a></li> <?php } ?> </ul> This shows TOP menu Menu but how to get SUB menu according to Dept of each menu.
      Thanks
    • By ETENTION
      Hi!
      Just started to dig into PW and since I have a small project starting I wonder that how does PW support dynamic forms out-of-the-box? Or perhaps through some module(s)?
      I'm creating a form(for visitors) that has options such as shape > size > color > availability/product which filter values for the last filter/select option (in this case availability).

      And is there any form field dependency implemented or is this just a matter of e.g. jquery events that trigger AJAX or visibility when field value is changed?