How to add a custom page block
Zotonic comes with a number of standard page blocks: Header, Text and Embed page. Additional page blocks are provided by modules, for example mod_survey uses page blocks extensively for composing surveys. Page blocks allow a content manager to add sophisticated sections of content, perhaps with configuration options. They could be used for design reasons e.g. for multi-column layouts, image carousels or floating elements. This cookbook item describes how to add a simple custom page block.
In order to add a custom page block, we need to register it, by editing an erlang file and adding two templates. For this tutorial we’ll add a page block which inserts the code for a music player from jamendo.com, a Creative Commons music hosting site.
To register the page block we add an observe_admin_edit_blocks/3
function to the site’s erl file e.g. apps_user/mysite/src/mysite.erl
:
%%====================================================================
%% support functions go here
%%====================================================================
-export([
observe_admin_edit_blocks/3
]).
observe_admin_edit_blocks(#admin_edit_blocks{}, Menu, Context) ->
[
{100, ?__("Media", Context), [
{music_player, ?__("Music Player | show an animated player", Context)}
]}
| Menu
].
The interesting parts are "Media"
, "Music Player"
and music_player
. "Media"
will appear as a section heading in the [+add page block]
drop down menu below the Standard page block types
section. "Music Player"
will appear, and is what the content editor clicks on to insert the page block. The music_player
atom is what Zotonic uses to figure out which templates to use, they will be created in the templates/blocks/
directory and will be called _admin_edit_block_li_music_player.tpl
and _block_view_music_player.tpl
.
As the name suggests, _admin_edit_block_li_music_player.tpl
is the template used on the edit form:
{% extends "admin_edit_widget_i18n.tpl" %}
{% block widget_title %}{_ Music Player _}{% endblock %}
{% block widget_show_minimized %}false{% endblock %}
{% block widget_id %}edit-block-music-player{% endblock %}
{% block widget_header %}{% endblock %}
{% block widget_content %}
<div class="control-group">
<label class="control-label">URL of the music widget</label>
<div class="controls">
<input type="text" id="block-{{name}}-url"
name="block-{{name}}-url"
value="{{ blk.url }}"
class="input-block-level"
placeholder="{_ Enter the url of the music widget _}"
>
</div>
</div>
{% endblock %}
For the purpose of demonstration, we extend the admin_edit_widget_i18n.tpl
template and use some template block tags.
Each time this page block is added, the form above will be displayed. Here, we want to allow users to easily embed a music widget from Jamedo, an online music community. The way do this is by adding extra input fields to the page through the edit templates.
Please note the values of the attributes of the input fields in the edit template. For example, name="block-{{name}}-url"
will expand to name="block-mus56h-url"
. The name
variable is a randomly generated string that is unique within every block template. The last portion of the value of the attribute is the attribute to be added to the resource. In this case, the attribute to be added will be url
.
Also note the value of the input’s value attribute. This ensures that if the attribute has already been saved against the resource being edited, then the input will be filled with the saved value. Without this, the data entered will not be saved.
This is all you need to be able to add a page block to the edit form. If you update your sitet, you should now be able to select the new page block. It just doesn’t display anything yet so let’s add blocks/_block_view_music_player.tpl
:
<iframe id="widget" scrolling="no" frameborder="0" width="400"
height="284" style="width: 400px; height: 284px;"
src="{{ blk.url }}"></iframe>
In the view template, a special variable called blk
is available. This blk
variable holds the attributes or properties of the page block. Since we added only one attribute, url
, to the edit template, the blk
variable will hold only two properties: name
, and our custom attribute, url
.
So if the user supplied http://widgets.jamendo.com/v3/album/40728?autoplay=0&layout=standard&width=400
, as the url to the music widget, the block’s frontend view template will expand to:
<iframe id="widget" scrolling="no" frameborder="0" width="400"
height="284" style="width: 400px; height: 284px;"
src="http://widgets.jamendo.com/v3/album/40728?autoplay=0&layout=standard&width=400">
</iframe>
We can extend this custom page block to allow the user to specify the widget’s height, width, and frameborder.
All you have to do is add new input fields in the page block’s edit template.