The Complete Guide to Social Engine 4 Module Development Part 6: Widgets and Pages
Widgets
Widget creation is one of the most common tasks in SE4 module development. Widgets are called “blocks” in the admin panel which in my opinion is a better term and for the rest of this post I will use blocks and widgets interchangeably. Widgets can contain forms, lists, menus and other widgets.
Widget codes are contained in a modules “widgets” path so a modules widgets path relative to the SE4 install directory is: application/modules/<Modulename>/widgets. Widget names are prefixed with the modules name (following the rules discussed in earlier posts) and a period (ex. core.html-block and core.comment). Widgets can also reside outside of a module which is the case if you decide to use SE4 SDK to create a widget package. These widgets reside in application/widgets and their names are not prefixed with a module name.
To create a widget we need to create a sub-directory in the widgets path. In our case we want to create a widget called “profile-cars”. This widget is meant to be used in the users’ profile page in the main page tabs similar to profile-videos and profile-albums in the Video module and Album module respectively. The name of the widget is “car.profile-cars” and the path is application/modules/Car/widgets/profile-cars. Within this directory we create Controller.php and index.php. We define a Controller class in Controller.php following this pattern:
With these in place we now have a complete widget. One way to test it is with the content view helper. You can use the following code to display a widget on any view script:
As it is our widget will render but we wont see anything in the browser since our index.tpl file is empty. We’ll get into that soon. First let us make sure that our widget is available for use in pages in the admin panel. To do that we need to add our widgets specs in our modules content.php file. This file is located in application/modules/Modulename/settings/content.php. This file contains the specifications of the widgets provided by the module.
Here is the list of the possible spec parameters, their possible values and what they mean:
- type — optional and defaults to “widget”.
- title — The title of the widget. This appears on the admin end as the label of the block in the available blocks list.
- description — The description of the widget. This appears on the admin end as the tool tip when hovering on the block.
- name — The name of the widget. This is the full name of the widget as discussed earlier. This is the name used in the name parameter when using the renderWidget of the content view helper. This is also name field of the engine4_core_content table then the changes in the page is saved.
- category — The available blocks list is categorized. The category is independent of the name of the module that contains the widget. You may create your own category or put your widget on an existing category. Note that the category name is case sensitive and that not setting this parameter will cause the widget to be unavailable in the layout editor.
- special — A non-empty value means the block is the first block on the category it is in. This also makes the background orange instead of green.
- autoEdit — A non-empty value means the edit form pop-up displays when the block is dropped on the page. The edit form pop-up for non-autoedit blocks only displays then the edit link is clicked on the block.
- adminForm — defines the structure of the block’s edit form in the layout editor. The elements of this form defines the block’s parameters. These parameters are stored as JSON in the engine4_core_content table’s params field. On the widgets controller all parameters can be retrieved with _getAllParams and individual parameters can be retrieved with _getParam. adminForm follows the following structure:
- Not setting this parameter means the edit form will only have the title field for editing. Errors will occur if this parameter is set incorrectly. When this parameter is set SE4 will automatically prepend the title field (if not manually defined) and append the “hide on mobile site” field.
- requirements — The page requirements of the widget that determines whether or not the widget will render. Pages (discussed below) have a provides field. This can be one of the following: no-subject, subject, subject=<item name>, viewer, no-viewer. A block that requires no-viewer will only render if the page is being viewed while the user is not logged in. A block that requires subject=car will only render if the page’s subject is a car. There are special cases of requires. These are header-footer and page-content. Widgets that require header-footer will only render when placed on the header/footer page fragments. Page-content is only used in the widget core.content which contains the rendered content of a view script if a controller invokes:
- isPaginated — a non-empty field means the page will be paginated and the parameter form will include the count field which determines the number of pages to show per page. Additional code must be written for paginated widgets discussed below.
- defaultParams — The default value of the parameters.
- canHaveChildren/childAreaDescription — only used in core.container-tabs.
Here is the specification of our car.profile-cars widget:
Here is the controller code:
Widgets have decorators and in the widget’s controller we can manipulate these decorators. We can also retrieve the widgets’ parameters and tell the widget to render or not render.
Any uncaught exceptions raised in the widget’s controller or view script will cause it not to render and messages will be written in the error log. In addition, if the site is in development mode messages will be shown via fire php. You may use $this->setNoRender(true) to cause the element not to render. You usually want the rest of the controller code to be skipped if you don’t want the widget to render so return $this->setNoRender(true) would be better.
By default widgets have two decorators: title and container. The generally have the following html structure:
We may use the outer most div’s class to be able to style the widget via css. The outer most div of the widget is the container decorator of the widget. This can be manipulated via $this->getElement()->getDecorator(‘container’) in the widget’s controller. The title decorator on displays if the title parameter is set in the layout editor or a default value is set in the widget specification. In the widgets controller these can be overwritten my manipulating the title decorator. $this->getElement()->getDecorator(‘title’)->setTitle(‘My Widget’) will set the widgets title to “My Widget” ignoring the values set in the layout editor or the widget specification.
Pages
Some of the views in social engine modules have views that can be edited via the layout editor in the admin panel. Examples are video browse page, album browse page and user/member profile page. In our car module we want the browse and view pages to be editable in the layout editor in the admin panel. Pages are instances of Core_Model_Page and are stored in engine4_core_pages and the description this table’s fields follows:
- page_id — the table’s primary key. This is the page query parameter of the layout editor.
- name — the name of the action that will render this page of the format <module-name>_<controller-name>_<action-name>.
- displayname — the name of the page as it appears in the layout editor.
- url — only applicable to custom pages.
- title — the title of the page. On the title tag this appears as <site title> — <page title>. The title tag can be manipulated via the headTitle view helper.
- description/keywords — appears on the meta description and the meta-tag of the page
- custom — a flag indicating if the page is created via the layout editor.
- layout — the layout that the page will use. Value must be one of the base names of the layout scripts in application/modules/Core/layout/scripts. Leaving this empty will use the aptly named layout script default.tpl.
- levels — only applicable to custom pages. Determines the user levels that can view this page.
- provides — what the page provides. Determines whether or not the widgets on this page will render or not. See above.
- view_count — the number of times the page has been viewed.
For non-custom pages the page structure are created when the module is installed via the callback class. In our car modules manifest.php we have:
(for a details about the manifest file see this page)
We define the Car_Installer class in application/modules/Car/settings/install.php:
This class’ onInstall method runs when the module is install and construct the pages that we need to be editable in the layout editor. Page construction involves checking the page already exists and creating it if it doesn’t. The first item that goes in the page is the main container. The main containers contain the sub-containers: top, right, bottom, left and middle. Finally sub-containers contain blocks/widgets.
The location and position of widgets/containers are saved in engine4_core_content. A brief description of the fields on this table follows:
- content_id — the tables primary key. In a widget’s controller this value can be retrieved by $this->getElement()->getIdentity(). This value is usually used on ajax paginated widgets like profile.cars
- page_id — the page_id of the page containing the widget/container
- type — widget or container
- name — the full name of the widget (<modulename>.<widget-name>) if type is widget or ‘main’, ‘top’, ‘right’, ‘bottom’, ‘left’ and ‘middle’ if type is container.
- params — not applicable for containers. For widgets this is the widget parameters as set in the layout editor
- parent_content_id — the content_id of the widget/container that contains this widget/container
- order — the other in which the widget/container as appears on its parent widget/container
- attribs — unused
This completes our discussion on widgets and pages.
Stuff that the end user can see. [The next part of the series we discuss background stuff — Tasks and Jobs.] The next part discusses forms and form elements.
Originally published in https://social-engine-tutorials.blogsplot.com.