Developer Intro: Part Three

Single Pages

Single Pages are different from the regular pages in your site. Custom Single Pages run unique code from PHP files placed in (your_site_root)/single_pages/mypage.php, giving you a way to create a front-facing interface for your application without needing to build it into a full-fledged block.

After your PHP script is in place, you’ll need to register it through your site’s Dashboard. This will set the page up in your sitemap, and let concrete5 know where to look for your custom code. This means that your Single Page has a static path. It cannot be dragged-and-dropped like a typical concrete5 page and continue to operate.

Single Pages are rendered using a special Page Type in your theme: view.php. When rendered, run any code that exists in your PHP file will be run. (Single Pages can also include editable areas, just like a regular page, but the star of the show is your custom code.) If you need to run something in the concrete5 environment, but it doesn’t need to be reusable, like a custom block-- a custom Single Page may be right for you.

Single Pages are also associated with their own controller files. These are located in your site’s controllers/ override directory, and the path and handle of your Single Page and its controller file must match. It’s a good idea to separate any programmatic logic from the Single Page itself and place it in the controller instead.


Attributes store data about the various components of concrete5. Attributes can be saved against pages, users and files. Each of these components has a set of standard properties (for instance, each Page has a name, a public date / time, etc). In addition to the standard set of attributes, custom attributes can be easily added through your site's Dashboard.

Each attribute has a type, which helps describe the type of data you're saving. For instance, the Exclude From Nav attribute only needs to be turned off or on, so it's best represented by the checkbox attribute. A user attribute that stores a nickname would likely be a text attribute. Many different attribute types are included in concrete5.

Attributes can also be arranged by set, much like files are arranged in the concrete5 File Manager, for easy grouping.

Tools Scripts

Tools scripts are a good choice when building a component that requires access to the concrete5 environment and make API calls, but doesn’t need to be its own stand-alone page. Tools scripts are therefore very handy for small utility functions.

The core tools directory contains many tools scripts used by the concrete5 core. To add a custom tools script, you’d place it in your overrides directory:


To run a custom tools file directly, you’d access it directly at the following URL:

Or use the concrete5 URL helper:

$uh = Loader::helper('concrete/urls');

Remember that your script must be run through the concrete5 dispatcher in order to load the concrete5 function and work-- this means if you're accessing it directly, it must be run through index.php/tools/myscript


Blocks represent the re-usable bits of functionality that can be added to your page’s areas directly through the user interface. Adding blocks is as easy as putting a page in edit mode, clicking an editable area and clicking Add Block. You’ll then be able to add any type of block currently installed on your site.

Block Types

Block types represent the various types of content that can be placed on your page. They can be as simple as a Content block, which lets you create and modify HTML code in a WYSIWYG editing environment, or as complex as a dynamic nagivation menu, image gallery or custom-coded form. concrete5 ships with a number of core block types, and more can be installed from our Marketplace or developed independently. Blocks take advantage of all the concrete5 components available to us, like the Sitemap for selecting pages, the File Manager for displaying and linking to files, etc. To view all the Block Types currently installed on your site, check out Dashboard > Stacks & Blocks > Block Types.

Common Block Components

While each block creates a different type of content, all blocks are built with common componentry. Blocks represent some of the strongest Model-View-Controller style organization in concrete5. Each block has a controller file that handles the processing and saving of data,add and edit interfaces for configuring the block, and a view layer for controlling how the block looks on the page. To check out these components, take a peek at the core blocks contained in:


To take a look at the core block controllers, go to:


Custom block templates

The appearance of a block can be changed on-the-fly by applying a Custom template to the block. Blocks with custom templates applied share the same block controller, add & edit experience, etc, but swap out the defauly view layer for a customized or refactored version. This is a great way to take the functionality already built into core blocks and make seamlessly integrate into a site’s design.

Tutorial: Example FAQ

If you want to see how we’d approach building a Single Page powered editing interface for concrete5, check out the Example FAQ add-on and its accompanying tutorial. This free package installs a new Dashboard Single Page that creates new pages on your site from the values you’ve specified. By looking through the source code, you can examine how the interface not only creates pages in a certain spot, but also assigns attributes to the page. It then allows management of the pages it has created directly through the Dashboard.

Blocks vs. Attributes

Both blocks and attributes save data to your site. So let’s think about which is best suited for particular challenges. When you find yourself needing a component that consists of content, visible on the page, and it needs to be re-used in many places on your site, a block is the best choice. Since it’s something that is well-served by the WYSIWYG experience, in-context editing is a natural approach.

Common components, like a page title, however, would be best stored as an attribute. This data may be displayed from time to time, but would usually be manipulated through the Dashboard, or the Page Properties screen, so it doesn’t need to exist as a block.


The concrete5 package format provides a way to bundle up all the custom components you’ve developed for concrete5, zip them up and make them easily installable through the Dashboard. You can then upload your package to the concrete5 Marketplace to be distributed for free, or for sale. Your package can include themes, blocks, custom templates, elements, helpers, single pages and more-- most anything that you add to as site. If you’re developing for a single site or project, you may not need to worry about packages. But it you’re interested in distributing your work, or simply making the custom components you’ve written more portable and easily re-usable, the package format will be of interest to you.

We can use the free “Example FAQ” package from our Marketplace as an example. Packages are installed to your packages overrides folder, so take a look inside:


Inside, you’ll notice that the package mimics the concrete5 overrides structure that you might already be familiar with. We have blocks/ directory and a page_list/ directory inside that contains, as you might expect, a custom template for the Page List block. We also see two Dashboard Single Pages and their accompanying controllers. These get installed along side the other Dashboard pages in your site.

To install all these components, the package includes a controller.php file in its root, which extends the core Package class. It sets a required minimum version of the concrete5 to ensure compatibility, sets the current version of the package itself, and then runs through a number of concrete5 functions to set up the various single pages, blocks, attributes and other components that the package includes.

Recent Discussions on this Topic

The actual tools urls are inverted?

I am using the latest ( version of C5 and it looks like the documentation on the tools directory scripts urls is wrong. I can access the upgrade script by typing concrete5/index.php/tools/upgrade/ while the documentation says that I should use …