Basic Block Development
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
- save data from editor input
- 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.
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