Concrete CMS 5.7 Add PageList Block Programmatically to Page

Mar 16, 2015

In this tutorial for Concrete CMS 5.7 we will programmatically add a PageBlock to a C5 Page. We find this useful for packages where we have a SinglePage and we want to load an Area with a PageList block. The page can also be a regular C5 Page based on a PageType. If you're building a Concrete Package that creates a new PageType such as "Property Listing" adding a SinglePage with a PageList block would enable you to install a page that shows all the properties.

Overview of Adding a PageList Block to a C5 Page

Let's start with a quick overview of the process we'll use to load the C5 Page, load the PageList BlockType and then add it to the Page.

First we need to load the Page where we want to add the PageList. This tutorial is from our C5 Razor Commerce addon and we're adding the PageList block to a SinglePage. We load the SinglePage using the Page::getByPath() function. Other options are Page::getByID() or Page::getCurrentPage().

Next we need to load the BlockType using BlockType::getByHandle(). The handle for PageList is 'page_list'. If you're adapting this tutorial to use with other block types one way to get a list of all the block type handles is to look in the BlockTypes DB table, column btHandle. A simpler way is too look into the folder /concrete/blocks/ the folder name for each block usually (not sure if this is mandatory) matches the handle. We need to create a $data array with required data for the Page List block. This is the most challenging part of the process and really the reason for making this tutorial because all the other steps are standard for any block. What is unique is that PageList has specific data fields required to add a new block.

We add the PageList Block to the Page using the Page->addBlock() function. We'll need a valid Area Name within our page to add the block. We've already loaded our BlockType and setup our array of required data so this function should run cleanly.

Step 1) Load the Page

// Add PageList Block
$shop_page = Page::getByPath('/shop');

Step 2) Get the PageList BlockType

$page_list_block = BlockType::getByHandle('page_list');

Step 3) Create the Data Params for the PageList Block

The easiest way we know of to find the PageList Block options is to use the C5 interface to add or edit a PageList block and use your browser inspector to view the "name" of the edit form elements. You'll find the name of the form elements matches, and this is because those options are automatically stored in the database by the parent BlockType Controller. This method has not been tested on every option available, but it works for the basic options we will start with below which are "num" and "includeName". Interestingly enough if you pass no options at all PageList Block will still be created without errors, but your pages shown will default to 0. And even if you add pages shown alone, no fields will be output. You need to output something, even if you don't want the page names in your PageList you will need to output description or other available fields.

$block_data = array(
  'num' => 25, // number of results
  'includeName' => true, // include page name
);

Step 4) Add the PageList Block to the Page

$shop_page->addBlock($page_list_block, 'Shop Content', $block_data);

Setting the PageType Option

Any of the PageList options found in the interface for adding PageList Blocks can be set by passing the $block_data to the Page::addBlock() function. In our programmatically created PageList Block we want to be able to filter by PageType. This is a common setting to use and will set the PageList to only return pages of a specific type.

The code to achieve this is simple notice the "ptID" param in the $block_data.

$block_data = array( 'num' => 14, // number of results 'includeName' => true, // include page name 'ptID' => 27, // show pages only of product type (ptID 27) );

The trick is we need to get that ptID (PageType ID) and usually we don't know it. If we have the PageType loaded already we could use $pt->getPageTypeID().

$block_data = array( 'num' => 14, // number of results 'includeName' => true, // include page name 'ptID' => $pt->getPageTypeID(), // show pages only of the PageType loaded into $pt );

If we don't already have the PageType we want loaded into $pt we can use PageType::getByHandle to load it.

use PageType;

$pt = PageType::getByHandle( 'product' );

$block_data = array( 'num' => 14, // number of results 'includeName' => true, // include page name 'ptID' => $pt->getPageTypeID(), // show pages only of the PageType loaded into $pt );

Adding Sort Options to the C5 PageList Block

We set the "orderBy" param in our $block_data array to set sorting options. The settings available to us include:

  • display_asc (Sitemap Order)
  • chrono_desc (Most Recent First)
  • chrono_asc (Earliest First) alpha_asc (Alphabetical order)
  • alpha_desc (Reverse alphabetical order)
  • random (Random)

$block_data = array( 'num'=> 25, // number of results 'includeName' => true, // include page name 'ptID' => $pt->getPageTypeID(), // show pages only of product type 'orderBy' => 'alpha_asc' // sort in alphabetical order );

Where to Run the Code to Programmatically Create PageList Blocks

If you're fairly new to coding or Concrete you may wonder where do I put this code and how might we have to adapt it for different contexts. In the use case this tutorial is based on this code is bundled into a function which is called by the Package installer PackageController::install function. This ensures that the code is only run once on the package install.

The code in this tutorial was actually tested in a SinglePage view! Probably not the best place to put it in any production site but for testing it allows us to experiment without having to uninstall/reinstall the Package it's being designed for. This allows us to refresh the single page and see the new block being instantly added. We can quickly delete old testing blocks in the interface.

Visit the original post at the Concrete Canada blog to see the options cheat sheet that we have there in the sidebar.

Recent Tutorials
Update jQuery to 3.5 on Concrete CMS version 8.5.x
Dec 1, 2021
By hissy.

If you have to take some time to fix your site to work with version 9 and want to update jQuery immediately, you can override it.

Add-On Developers: Get Your Add-Ons Ready for Concrete CMS 9.0
Aug 6, 2021
By andrew.

Concrete CMS 9.0 is coming! But there are some changes in version 9 that might affected your add-ons and themes. This document aims to answer questions about the most common ways that your add-ons might need to be changed, and common problems you'll run into.

Permissions for editors in a multilingual site
Jun 2, 2021
By myq.

How to set up a multilingual Concrete CMS site for groups of language-specific editors

Getting Started with Doctrine in Concrete CMS
Jan 20, 2021
By linuxoid.

Doctrine is a very flexible, simple (once you get to know it better) and powerful PHP library for database interactions primarily focused on the ORM = Object Relational Mapping and DBAL = DataBase Abstraction Layer.

How To Upgrade PHP Using the MultiPHP Manager In cPanel
Nov 23, 2020

This article will explain how to upgrade your PHP version using cPanel.

How To Add Google Analytics To Your Website - The easy way
Oct 9, 2020

Adding analytics to your website is an important part of running your website. There’s no need to edit your theme or install a plugin to add a tracking code to Concrete CMS you can do it right from the CMS.

Was this information useful?
Thank you for your feedback.