Basic Block Development

Part One

Introduction

After watching these videos, you should know everything you need to put together your own blocks using php, css and javascript. These videos come from live training sessions with Andrew, concrete5's CTO. Since were recorded live, the theme jumps around a little, but the discussions are interesting.

First Steps

When you look at a concrete5 page full of content, what you are actually seeing is a "collection of blocks". In the early days of concrete5, pages were actually referred to as collections. These collections of blocks can be made of many different "block types": html, content, image, form, etc. So when you are going to "make a new block", you are actually creating a new block type.

At its basic level, a block is a collection of files. To understand this better, open up the folder concrete/blocks/html/ and take a look at all those files. These are being used when Andrew talks about a "view layer", "add layer" etc.

Here's what's going on in there:

  • view.php: This contains the code that gets rendered on the page.
  • add.php / edit.php: These are the files that are loaded when you add or edit a block, theses have the code that editors see when working on a site. Usually these only have on line that includes a different file.
  • form_setup_html.php: This file is in almost all blocks, and it contains the code that actually gets used when either add or edit is opened.

Those files handle all the normal display functionality of the block. A block can have a couple other views, but those are covered later on in Advanced Block Development.

That said, blocks need data to be useful. You could totally write a block with a view.php that contains this: <span class="boring">Wow what a lame block</span>, but that would be lame. Blocks all have controllers and database entries. This is because concrete5 is all about the model-view-controller architecture.

Here it is in a nutshell and how it is applied in concrete5:

  • Model : raw data (Kind of, "ideas" is more accurate.)
  • View : display code
  • Controller : Interface to send data from the model to the view, and also to send input back to the model to manipulate data.

You can read the wikipedia page if you're interested, or use your favorite search engine and get a number of opinions on what it really means.

So views are taken care of. How about the other two? For a concrete5 block, you have these two files:

  • db.xml : a definition of your block as it is represented in the database. This file exists so you do not need to muck around in SQL to create what a block needs to use. The actual data for your site is stored in an SQL database. You already know that.
  • controller.php : At its most basic level, this file does two things
    1. save data from editor input
    2. request data from the db to pass to the view.

Controllers can also do whatever fancy things you want to program them to do. If you opened up the html block's controller.php and were flabergasted at its emptiness, you will want to open the file concrete/core/controllers/blocks/html.php. This is part of concrete5's powerful "override" structure, which allows your application to be totally separate from the core code, and it allows you to even borrow code from the core without breaking anything. But you don't need to worry about that now.

Another thing you do not need to worry about right now is that db.xml files are not where the "model" concept stops in concrete5.

Check out db.xml!

Here is the content of the db.xml for the html block that Andrew is talking about:

  <?xml version="1.0"?>
  <schema version="0.3">
     <table name="btContentLocal">
        <field name="bID" type="I">
           <key ></key>
           <unsigned ></unsigned>
        </field>
        <field name="content" type="X2">
        </field>
     </table>
  </schema>

So basically you have a table named after your block, prefixed with bt. As Andrew points out, we use the ADODB library to manage our database stuff. So a valid block will have at least one <table> and some <field> entries for data. Blocks are always going to key on the bID. The rest is basically up to the whim of the developer.

If you want to know more about db.xml, check out this manual for the ADODB Data Dictionary. Search "portable type codes" to find the different kinds of data you can store. Generally you'll only be storing numbers and text in a concrete5 database. BLOBs are not recommended since all your files are going to be in concrete5's file manager.

Back to the controller

Andrew explains a few of the variables within a block. Go ahead and open up the block controller for the html block so you can see them in place.

  • $btTable : This is always the name of the table you created in db.xml.
  • $btInterfaceWidth : How wide the dialog will be when someone edits or adds this block.
  • $btInterfaceHeight : Same thing but height.
  • $btWrapperClass : You can specify any class that you want to add to your block. Andrew mentions that you will usually want this to at least have "ccm-ui". Anything wrapped in a "ccm-ui" class will have the mighty Twitter Bootstrap available to it.

And yes,there are a few other variables up top there, but we needn't worry about them for now.

Add and Edit

As Andrew points out, most add / edit dialogs are going to share a generic form, but it is possible to have a little extra in add.php or edit.php. You also get your add / save and cancel buttons for free, but you will need to add some form fields to the form you include in order to actually add anything to your block.

In order to make your form work, you need to name your fields in such a way that the blocks controller is able to save the field to the database. This means you just name the field the same name as the db column. So check out the HTML block's form_setup_html.php and db.xml and note that name="content" is in both of those.

As Andrew points out, the textarea for the HTML block could be as simple as:

<textarea name="content"><?=$content?> </textarea>

and it will still work.

Andrew goes on to point out that a block will take care of this for you automatically, but there are cases where you may want to add a little preprocessing. Don't worry about validating data! Blocks have their own validate() but we cover that in the advanced session.

More Controller

Andrew points out that if you want to do more in an edit dialog, you can also add an edit() function to your block's controller that will allow you to do a little work before opening up that dialog. He also introduces the $this->set() function in controllers which is the fundamental means of passing data from a controller to any view. Whatever string is passed into set() will end up in the controller as a variable.

There are also two nice little functions you should make use of:

  • getBlockTypeName : The name of your block that will be shown in the block-picker dialog when adding a block.
  • getBlockTypeDescription : This is a sentence-long summary of your block.

Back to add / edit

The file auto.js is loaded whenever the add / edit dialog is loaded. This can be used for any kind of javascript you think would be useful, for instance if you wanted to load a gallery of web fonts or some kind of fancy form that watches what peope are typing into fields etc. Andy also mentions validation briefly, but that will be covered in the advanced section.


Recent Discussions on this Topic

Custom Block View Tutorial

Attached is a white paper on creating custom block views. I am finding many C5 users do not understand this concept and even hesitate to modify purchased addons. I hope this is helpful. Please PM me if you have any additions or corrections and I …

Building a block with library image input?

I'm trying to build a block that has the ability to pull an image from the library (or, since I'm desperate, from anywhere, even a remote URL), but I can't figure it out, and I'm new to PHP... Does anyone have any pointers? I tried reading http://phple…

Adding smarter DISQUS to your concrete5

Guys, I've just finished figuring out a smarter way to implement Disqus, a third-party commenting system Sometime, you don't bother users to register on your site, but comment using Facebook, twitter or other social ID. Disqus is a fine comment s…

Check it out: custom block creator!

*** This package is now available on the marketplace: http://www.concrete5.org/marketplace/addons/designer-content/ *** I've made a "custom block creator" which aims to solve the problem of allowing you (as the site designer) to specify exactly how som…

Check if block is empty

Hi guys, I need some help with this: I need to check if a block is empty (essentially the 'C' field). If the 'C' (content?) field is empty I want serve a conditional accordingly. I have tried the following unsuccessfully; [code] $block = Block::getBy…