Simple Modules
Modules in FUEL can range from simple forms to a complex, interactive, multi-page interface. Simple modules don't require additional views and controllers to be created. Common examples of simple modules include events, news and job postings.
For more on creating a simple module, view the user guide's tutorial.
Configuring
A simple module usually contains a single model that maps to a database table (e.g. news). It is recommended that you create your model first (click here for an example). After your model has been created, you can activate and configure the module in the config/MY_fuel_modules.php file like so:
$config['modules']['example'] = array();
This will create a module that maps to the model named example_model and will have the friendly name of Example.
The above could actually be written a longer way as follows:
$config['modules']['example'] = array( 'module_name' => 'Example', 'module_uri' => 'example', 'model_name' => 'example_model', 'model_location' => '', 'display_field' => 'name', 'preview_path' => '', 'permission' => 'example', 'instructions' => 'Here you can manage the examples for your site.', 'archivable' => TRUE, 'nav_selected' => 'example' );
Additional Configuration Parameters
Below is a list of all the parameters you can specify to further customize your module. Many of them base their default values on the key value specified in the config (e.g. example):
Preference | Default Value | Options | Description |
---|---|---|---|
module_name | The default value is a humanized version of the module key (e.g. a key of example = Example) | None | the friendly name of the module. |
module_uri | The default is the module key (e.g. example) | None | the URI path to the module that will appear after fuel. |
model_name | The default is the module key with the suffix of _model (e.g. example_model) | None | the name of the model |
model_location | By default it will look in the application/model folder. If a value is given it will look in the modules/{model_location}/model folder | None | The module folder location of the model. |
view_location | By default it will look in the application/views folder. If a value is given it will look in the modules/{view_location}/views folder | None | the location of the view files |
display_field | The default is the field name. If you do not have a field of name, you must specify a new field | None | The model field to be used for display purposes |
js_controller | The default is BaseFuelController | None | The name of the javascript controller. If an array is given, then the key of the array is considered the module folder to look in and the value the name of the controller. The js_controller_path will automatically be changed to the module's assets folder if no js_controller_path is provided. For more information on creating javascript controllers, visit the section on the javascript jqx Framework |
js_controller_path | The default is the path to the fuel module's asset folder (e.g. fuel/modules/fuel/assets/js/ | None | The base path of where to look for the controller file. |
js_controller_params | None | None | Parameters to pass to the jqx controller. They must be in the form of a json object |
js | None | None | additional javascript files to include for the module |
preview_path | None | None | The URI path to preview the information from the module in the website |
views | Built in FUEL pages | None | View files for the list, form and delete pages |
permission | The default is the module key (e.g. example) | None | The name of the permission that users must be subscribed to to have access to the module. |
edit_method | The default is find_one_array filtered on the id value passed to the form | None | The model's method to retrieve the information to edit. |
instructions | None | None | The instructions to provide users when creating or editing |
filters | None | None | Fields to filter the values in the list view |
archivable | TRUE | Boolean Value TRUE/FALSE | Saves to the archive table for later retrieval if you need to revert back |
table_actions | EDIT, VIEW, DELETE | None | The actions per row to include in the table view |
item_actions | save, view, publish, activate, delete, duplicate, create | save, view, publish, activate, delete, duplicate, create, others | The form level actions to include in the toolbar. The others action is a key / value array with the key being the FUEL URI and the value being the button label. It can be used to create additional custom buttons. Each button will submit the form information on the page to the link path of the button. |
list_actions | None | None | Other HTML to be displayed at the top above the list table |
rows_selectable | TRUE | Boolean Value TRUE/FALSE | A boolean value that will set the whole row to be clickable |
precedence_col | precedence | None | The name of the column to contain the custom precedence sorting information |
clear_cache_on_save | TRUE | Boolean Value TRUE/FALSE | Clears the cache upon saving new or updated values to a record |
create_action_name | Create | None | The name of the button to be used for creating an item |
configuration | None | None | Additional configuration files to load |
nav_selected | None | None | The left navigation item to be selected |
table_headers | None | None | The columns to use for the table view |
default_col | The default is the second column of the table (e.g. the one normally after the id column) | None | The default field to sort on |
default_order | asc | asc, desc | The default field ordering |
sanitize_input | TRUE | Boolean TRUE/FALSE, string of "xss", "php", "template" OR "entities", OR an array for multiple values e.g. array('xss', 'php', 'template', 'entities'). See the FUEL configuration for changing the different sanitization callbacks. | Cleans the input before inserting or updating the data source |
sanitize_files (was sanitize_images) | TRUE | Boolean Value TRUE/FALSE | uses xss_clean function on images |
displayonly | None | Boolean Value TRUE/FALSE | Will only display the data and not allow you to save it |
language | None | None | Additional language files to load |
language_col | language | None | The column name that contains the language key value |
hidden | FALSE | Boolean Value TRUE/FALSE | If set to TRUE, it will hide the module in the admin menu |
disabled | FALSE | Boolean Value TRUE/FALSE | If set to TRUE, it will hide the module in the admin menu as well as show a 404 |
icon_class | None | None | The CSS icon class to associate with the module |
folder | None | None | The advanced module folder in which it lives in |
exportable | FALSE | Boolean Value TRUE/FALSE | Will display an "Export" button on the list view page that will allow users to export the currently filtered list data |
limit_options | array('25' => '25', '50' => '50', '100' => '100') | array | The "Show" options displayed in the list view |
advanced_search | FALSE | Boolean Value TRUE/FALSE | If TRUE, this will display model filters in an advanced search menu |
disable_heading_sort | FALSE | Boolean Value TRUE/FALSE | If TRUE, this will disable heading sorting on the list view |
description | None | None | A description value that can be used in the site docs |
pages | array | None | Can automatically generate pages for your module including list pages, detail pages, related category and tag pages, search pages and your own custom pages. Leverages
by default the fuel/application/views/_posts/ view files but that can be overwritten.
'pages' => array( 'base_uri' => 'media', 'layout' => 'posts', 'list' => 'media/list', 'post' => 'media/detail', 'archive' => array('route' => 'media/archive(/$year:\d{4})(/$month:\d{1,2})?(/$day:\d{1,2})?', 'view' => 'media/list', 'layout' => 'main', 'method' => 'my_test_method', 'empty_data_show_404' => TRUE), 'tag' => array('route' => 'media/tag/($tag:.+)', 'layout' => 'main', 'view' => 'media/list', 'empty_data_show_404' => TRUE), 'custom' =>array('route' => 'media/custom', 'view' => 'media/list', 'method' => 'my_custom_method')); |
The Model
The module's model is the most important piece of a module. It is what drives the the saving, form and extra interactions needed for the module to work. A module should extend the abstract Base_module_model class which is a child of the MY_Model class and is found in the modules/fuel/model folder. Custom record object should extend the Base_module_record
There are several methods that you can add/overwrite to give you greater functionality for your module (view the tutorial for more information).
- list_items()
- tree()
- form_fields()
Additionally, there are several hooks you may want to use that allow you to insert functionality during the saving and deleting process of a modules record.
The Views
Simple modules are made up of several views:
- List view - where you can filter and select from a list and edit, delete or preview.
- Form view - the form view that allows you to edit or input new records for the module
- Tree view (optional) - provides a tree like hierarchical structure. Requires a tree method on the module's model that follows the hierarchical Menu structure
- Preview view (optional) - the URO to the website to preview the module
Filtering the List View
The list_items() method provides some ways to make it easier to search and filter your list results. By default, a simple module comes with a single search field that will use the module's display_field configuration parameter to search in. If you want the primary search field to be different then the display_field, you must specify the search_field parameter in the module's configuration (most of the time, these will be the same so you will not need to use the search_field configuration).
$config['modules']['articles'] = array( ... 'display_field' => 'title', 'search_field' => 'content', ... );
To search in multiple fields, use the module model's filter property as shown here:
public $filters = array('title', 'slug', 'content');
Filtering Form Fields
If a single search field isn't enough, you can specify a form using the Form_builder array syntax in the module's configuration:
$config['modules']['articles'] = array( ... 'filters' => array( 'post_date' => array('type' => 'datetime'), 'published' => array('type' => 'enum', array('yes', 'no')), ), ... );
Or, you can create a filters() method on the module's model like so to create the form fields:
public function filters() { $fields['post_date'] = array('type' => 'datetime'); $fields['published'] = array('type' => 'enum', array('yes', 'no')); return $fields; }
Operator Suffixes
The default operator is LIKE %{term}% however, you can use the following suffixes for your filter names to use different operators:
- _from: ">"
- _fromequal: ">="
- _to: "<"
- _toequal: "<="
- _equal: "="
- _id: "="
public function filters() { $fields['post_date_to'] = array('type' => 'datetime'); $fields['post_date_from'] = array('type' => 'datetime'); return $fields; }
Additionally, using _having will perform a having condition on the SQL which is helpful for filtering on values generated in the SELECT of the SQL.
Advanced Search
The filter fields will by default be put to the left of the search box. However, if you have a lot of filter fields that area will get crowded quickly. To help with this issue, there is an advanced_search module configuration that can have the following values:
- FALSE: Will display filter fields next to the search box
- TRUE or popup: Will display a triangle icon in the search box that will display the fields when clicked.
- collapse: Will display a collapsible area above the list (new in 1.3).
$config['modules']['articles'] = array( ... 'advanced_search' => 'collapse', ... );
AND & OR
The SQL generated will by default use "OR". To use "AND", change the module model's filter_join property like so:
public $filter_join = 'and';
To combine AND and OR, you can use an array like so:
public $filter_join = array('title' => 'or', 'content' => 'or', published' => 'and');
Joins
Often, you'll need to join one or more tables together. You can use CodeIgniter's active record and add it to the list_items method like so:
public function list_items($limit = NULL, $offset = NULL, $col = 'statement_date', $order = 'asc', $just_count = FALSE) { $this->db->join('fuel_categories', 'fuel_categories.id = articles.category_id', 'LEFT'); $this->db->select('articles.id, article.title, fuel_categories.name as category, articles.published'); $data = parent::list_items($limit, $offset, $col, $order, $just_count); return $data; }
Or you can add a _common_joins() method (new to 1.3). The _common_joins method will be used for all "find_", options_list and list_item methods on the module's model.
public function _common_joins() { $this->db->join('fuel_categories', 'fuel_categories.id = articles.category_id', 'LEFT'); }
Sometimes joins will require you to prefix the field with the table name. Periods can be problematic so you can substitute it using a ":".
public function filters() { $fields['fuel_categories:name'] = array('label' => 'Category name'); $fields['post_date_to'] = array('type' => 'datetime'); $fields['post_date_from'] = array('type' => 'datetime'); return $fields; }
Friendly Filter Text
When multiple filters are being used to filter the list view, there is friendly text that appears above the list as of 1.3. This is controlled by the Base_module_model::friendly_filter_info() method. To alter the returned value you can simply overwrite this method in your module's model.
Remember, you can always simply just overwrite the list_items() method on the module's model with your own logic to filter the results.
Module Overwrites
Module overwrites allow for you to overwrite existing module parameters. For example, if you'd like to overwrite the built-in FUEL fuel_pages_model to incorporate your own model hook you've added to the MY_pages_model, you can do so like so:
$config['module_overwrites']['pages']['model_name'] = 'MY_pages_model';
Generated Post Pages
New to FUEL CMS 1.3 is the ability to create post type pages automatically from your modules. This is a very powerful feature that allows you to map routes to post pages that have specific behaviors. This means each module can now have blog like features (minus the commenting). It uses the Fuel_posts class to do so. There are a number of types of pages automatically created for you (basically the ones we were tired of creating over and over again) including, slug, archive, list, post, tag and archive pages. For example, if you have a module's model that has a foreign_key property to the fuel_categories_model and a has_many to the fuel_tags_model, tag and category pages can be automatically generated using the pages parameter. To make it easier, there is a Base_posts_model class that your module's model can inherit from (which already inherits from the Base_module_model class).
Below is an example of an "articles" module with the pages parameter being used in a module's configuration:
The articles SQL:
CREATE TABLE `articles` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `title` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '', `slug` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '', `content` text COLLATE utf8_unicode_ci NOT NULL, `excerpt` text COLLATE utf8_unicode_ci NOT NULL, `image` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '', `featured` enum('yes','no') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'yes', `publish_date` datetime NOT NULL, `category_id` int(10) unsigned NOT NULL, `published` enum('yes','no') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'yes', PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
The module's model (note that it inherits from the Base_posts_model):
<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); require_once(FUEL_PATH.'models/Base_posts_model.php'); class Articles_model extends Base_posts_model { public $name = 'articles'; function list_items($limit = NULL, $offset = NULL, $col = 'publish_date', $order = 'desc', $just_count = FALSE) { // add any $this->db->select('....') or $this->db->join(...) here $data = parent::list_items($limit, $offset, $col, $order, $just_count); return $data; } function form_fields($values = array(), $related = array()) { $fields = parent::form_fields($values, $related); // put in your own specific code to manipulate the fields here return $fields; } } class Article_model extends Base_post_item_model { }
The following global page parameters can be used with the pages parameter for your module:
- base_uri: the main base URI path to the
- layout: the main layout to be used for the pages generated that don't have it explicitly specified
- vars: an array of variables to be sent to the generate pages
- per_page: how many pages to display per page if pagination is needed
Additionally, each slug, archive, list, post, tag and archive page can have it's own parameters specified like so:
- route: the route to the pages. Note in the example below that you can specify the URI parameter variable names by prefixing $name: in the captured area (e.g. (/$year:\d{4}))
- view: the view to use for the page. By default, it will look in the application/views/_posts folder
- layout: will overwrite the global layout specified
- method: the method on the model to use for getting the data. If nothing is specified it will use the defaults in the Fuel_post class
- vars: specific page variables to pass to the pages at the specified route
- per_page: will overwrite global page parameter setting for many pages to display per page if pagination is needed
- empty_data_show_404: determines whether to display a 404 error if the data is empty or not
Lastly, you can of course create your own custom set of pages generated by your module and are not limited to the default. To do this, take advantage of the method parameter and specify a method on your model to generate the data you want to pass to your view and specify a relevant route parameter.
Below is an example of the pages parameter being used in a module's configuration with an example of a way to define "custom" generated pages:
... 'pages' => array( 'base_uri' => 'articles', 'per_page' => 10, 'layout' => 'posts', 'list' => 'articles/list', 'post' => 'articles/detail', 'archive' => array('route' => 'articles/archive(/$year:\d{4})(/$month:\d{1,2})?(/$day:\d{1,2})?', 'view' => 'articles/list', 'layout' => 'main', 'method' => 'my_test_method', 'empty_data_show_404' => TRUE), 'tag' => array('view' => 'articles/list', 'empty_data_show_404' => TRUE, 'per_page' => 5), 'custom' => array('route' => 'articles/custom', 'view' => 'articles/list', 'method' => 'my_custom_method') ), ...
Separate Classes for Model Logic
For larger models, the list_items method form_fields method, the validation logic and even the related items area can become a bit much to have in one model. FUEL 1.3 added the ability to inherit from four new classes to make it easier to separate that logic out. To add this functionality, there are now four new properties that can be utilized on a module model:
public $list_items_class = ''; // a class that can extend Base_model_list_fields and manipulate the list_items method public $form_fields_class = ''; // a class that can extend Base_model_fields and manipulate the form_fields method public $validation_class = ''; // a class that can extend Base_model_validation and manipulate the validate method by adding additional validation to the model public $related_items_class = ''; // a class that can extend Base_model_related_items and manipulate what is displayed in the related items area (right side of page)
Custom Classes
All custom classes come with the following methods that can be used with the class
- set_parent_model: Sets the main parent model (done upon initialization)
- get_parent_model: Returns the main parent model
- set_values: Sets the current record's values (if any... done upon initialization)
- append_values: Appends values to the existing values store.
- get_values: Returns an array of the values stored
- get_value: Returns a specific value and must pass the key name of the value
- record: Returns a record object of the current records value (if any)
Custom List Items Class
To create your own custom form fields class, specify the class name for the model's $list_items_class property, and then create a class that inherits from Base_model_list_items (see below). In the initialize method, you can specify your field logic or even break it out into additional methods to keep it better organized. The example below does this and creates separate "Info" and "Meta" tabs.
<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); require_once(FUEL_PATH.'models/Base_module_model.php'); class Articles_model extends Base_module_model { ... public $list_items_class = 'Article_list_items'; // a class that can extend Base_model_list_items and manipulate the list_items method ... } // -------------------------------------------------------------------- class Article_model extends Base_module_record { // put your record model code here } // -------------------------------------------------------------------- class Article_fields extends Base_model_list_items { public function fields($values = array()) { $f = $this->get_parent_model()->form_fields(); $fields =& $this->fields; $fields['title'] = $f['title']; $fields['slug'] = $f['slug']; $fields['category_id'] = $f['category_id'] $fields['publish_date_from'] = array('type' => 'date'); $fields['publish_date_to'] = array('type' => 'date'); return $fields; } public function process($data) { foreach($data as $key => $val) { $data[$key]['title'] = htmlentities($val['title']); } return $data; } }
The Base_model_list_items class provides the follow additional methods:
- fields: Uses a Base_model_fields class to create form fields for filtering the list (see next section for Base_model_fields class
- add_filter: Adds a filter to the model's property
- add_filters: Adds multiple filter values to the model's filters property
- add_filter_join: Sets the filter_join property on the model
- select: Runs a select statement on the model's active record query for the list view
- join: Runs a join statement on the model's active record query for the list view
- friendly_info: Creates friendly text explaining what is being filtered
- process: This methods allows for further processing of the data and provides the array of data to process as a parameter to the method
Custom Form Fields Class
To create your own custom form fields class, specify the class name for the model's $form_fields_class property, and then create a class that inherits from Base_model_fields (see below). In the initialize method, you can specify your field logic or even break it out into additional methods to keep it better organized. The example below does this and creates separate "Info" and "Meta" tabs.
<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); require_once(FUEL_PATH.'models/Base_module_model.php'); class Articles_model extends Base_module_model { ... public $form_fields_class = 'Article_fields'; // a class that can extend Base_model_fields and manipulate the form_fields method ... } // -------------------------------------------------------------------- class Article_model extends Base_module_record { // put your record model code here } // -------------------------------------------------------------------- class Article_fields extends Base_model_fields { public function initialize($fields = array(), $values = array(), $parent_model = NULL) { $fields =& $this->fields; $this->set_label('title', 'Headline'); $this->remove(array('date_added')); $this->info_tab(); $this->meta_tab(); } public function info_tab() { $info_fields = array('title', 'slug', 'content', 'excerpt', 'image'); $this->tab('Info', $info_fields); } public function meta_tab() { $meta_fields = array('tags', 'category_id'); $this->tab('Meta', $meta_fields); } }
The Base_model_fields class provides the follow additional methods:
- set_fields: Sets the fields for the object and happens upon initialization
- get_fields: Returns an array of field information
- get_field: Returns a single field's information
- set: Sets a field's information
- get: Returns a single field's information
- remove: Removes a field
- tab: Creates a tab with the specified fields
- clear: Clears the field information
- reorder: Reorders the fields in the specified order
Note that in the example above the various ways to conveniently set field properties using the "set_" magic method. You can mass assign values to multiple fields. Below is an example of how to hide multiple fields at once:
$this->set_type(array('field1', 'field2'), 'hidden');
Additionally you can specify a single property by passing an array:
$this->set_comment(array('field1' => 'Comment 1', 'field2' => 'Comment 2'));
Lastly, you can just create a single field value using just the set method:
$this->set('field1', array('label' => 'Field 1 label', 'type' => 'textarea'));
Custom Validation Class
A custom validation class is convenient for separating your model validation logic outside of your model class. The following are additional methods that can be used on the validation class:
- add: Adds a validation rule using the Validator class that is set on the parent model
- remove: Removes a validation rule
- validate: Runs through the validation rules to validate and returns a boolean value
- set_validator: Sets the validator object to use for validation. The default object is the one already attached to the model
- get_validator: Returns the validator object used for validation
- add_error: Adds an error to the validation object
Custom Related Items Class
The custom related items class can be used to display information that appears to the right of the form fields.
- vars: By default the following variables are passed to the view file:
- values: The saved values for the record
- rec: An instance of the record being editing
- model: The model object
- CI: The main CodeIgniter object
- fuel: The main FUEL object (e.g. $CI->fuel)
- class: The name of the class
- ref: A reference to the related items class
- view: The path to the view file. If a key/value array is passed, the key will be the advanced module folder and the value will be the path to the view
- set_output: Sets the output string for rendering
- get_output: Returns the output string for rendering
- render: Renders the view file if it exists and returns the output string
- display_if_new: Displays the related items area even if it is a new record. Default is TRUE
... class Article_related_items extends Base_model_related_items { public function initialize($values, $parent_model) { // if view is in an advanced module $this->view(array(MY_MODULE_FOLDER => '_admin/article_related_items')); // OR ... if view is in the main application folder $this->view('_admin/article_related_items'); } }