- Patch #735196 by jhodgdon, sun: improve hook_filter_info() documentation.

merge-requests/26/head
Dries Buytaert 2010-12-09 02:04:16 +00:00
parent f2b57f2072
commit f3a9f68002
2 changed files with 208 additions and 130 deletions

View File

@ -14,114 +14,29 @@
/**
* Define content filters.
*
* Content in Drupal is passed through a group of filters before it is output.
* This lets a module modify content to the site administrator's liking.
* User submitted content is passed through a group of filters before it is
* output in HTML, in order to remove insecure or unwanted parts, correct or
* enhance the formatting, transform special keywords, etc. A group of filters
* is referred to as a "text format". Administrators can create as many text
* formats as needed. Individual filters can be enabled and configured
* differently for each text format.
*
* This hook allows modules to declare input filters they provide. A module can
* contain as many filters as it wants.
*
* The overall, logical flow is as follows:
* - hook_filter_info() is invoked to retrieve one or more filter definitions.
* - The site administrator enables and configures the filter, where the
* following properties may be used:
* - 'title': The filter's title.
* - 'description': The filter's short-description.
* Additionally, if a filter is configurable:
* - 'settings callback': A form builder function name providing a settings
* form for the filter.
* - 'default settings': An array containing default settings for the filter.
* - When a form containing a text format-enabled text widget/textarea is
* rendered, the following property are checked:
* - 'tips callback': A function name providing filter guidelines to be
* displayed in the text format widget.
* - When a content using a text format is rendered, the following properties
* may be used:
* - 'prepare callback': A name of a function that escapes the to be filtered
* content before the actual filtering happens.
* - 'process callback': The name the function that performs the actual
* filtering.
* This hook is invoked by filter_get_filters() and allows modules to register
* input filters they provide.
*
* Filtering is a two-step process. First, the content is 'prepared' by calling
* the 'prepare callback' function for every filter. The purpose of the 'prepare
* callback' is to escape HTML-like structures. For example, imagine a filter
* which allows the user to paste entire chunks of programming code without
* requiring manual escaping of special HTML characters like @< or @&. If the
* requiring manual escaping of special HTML characters like < or &. If the
* programming code were left untouched, then other filters could think it was
* HTML and change it. For most filters however, the prepare-step is not
* necessary, and they can just return the input without changes.
* HTML and change it. For many filters, the prepare step is not necessary.
*
* Filters should not use the 'prepare callback' step for anything other than
* escaping, because that would short-circuit the control the user has over the
* order in which filters are applied.
*
* The second step is the actual processing step. The result from the prepare
* step gets passed to all the filters again, this time with the 'process
* callback' function. It's here where filters should perform actual changing of
* the content: transforming URLs into hyperlinks, converting smileys into
* images, etc.
*
* An important aspect of the filtering system is 'text formats'. Every text
* format is an entire filter setup: which filters to enable, in what order
* and with what settings.
*
* Filters that require settings should provide the form controls to configure
* the settings in a form builder function, specified in 'settings callback'.
* The filter system stores the settings in the database per text format.
*
* If the filter's behavior depends on an extensive list and/or external data
* (e.g. a list of smileys, a list of glossary terms) then filters are allowed
* to provide a separate, global configuration page rather than provide settings
* per format. In that case, there should be a link from the format-specific
* settings to the separate settings page.
*
* The $filter object with the current settings is passed to the 'settings
* callback' function. If 'default settings' were defined in hook_filter_info(),
* those are passed as second argument to the 'settings callback'. Each filter
* should apply either the default settings or the configured settings contained
* in $filter->settings.
*
* 'settings callback' is invoked with the following arguments (most filter
* implementations will only need $form_state, $filter and $defaults):
* - $form: The prepopulated form array, which will usually have no use here.
* - &$form_state: The form state of the (entire) configuration form.
* - $filter: The filter object containing settings for the given format.
* - $format: The format object being configured.
* - $defaults: The default settings for the filter, as defined in 'default
* settings' in hook_filter_info().
* - $filters: Complete list of filter objects that are enabled for the given
* format.
*
* @code
* function mymodule_filter_settings($form, &$form_state, $filter, $format, $defaults, $filters) {
* $settings['mymodule_url_length'] = array(
* '#type' => 'textfield',
* '#title' => t('Maximum link text length'),
* '#default_value' => isset($filter->settings['mymodule_url_length']) ? $filter->settings['mymodule_url_length'] : $defaults['mymodule_url_length'],
* );
* return $settings;
* }
* @endcode
*
* 'prepare callback' and 'process callback' are invoked with the following
* arguments:
* - $text: The text to be filtered.
* - $filter: The filter object containing settings for the given format.
* - $format: The format object of the text to be filtered.
* - $langcode: (optional) The language code of the text to be filtered.
* - $cache: Boolean whether check_markup() will cache the filtered $text in
* {cache_filter}.
* - $cache_id: The cache ID used for $text in {cache_filter} when $cache is
* TRUE.
*
* @see check_markup()
*
* 'prepare callback' and 'process callback' functions may access the filter
* settings in $filter->settings['mymodule_url_length'].
*
* 'tips callback' is invoked with the following parameters:
* - $filter: The filter object containing settings for the given format.
* - $format: The format object of the text to be filtered.
* - $long: Boolean whether to return long or short filter guidelines.
* The second step is the actual processing step. The result from passing the
* text through all the filters' prepare steps gets passed to all the filters
* again, this time with the 'process callback' function. The process callbacks
* should then actually change the content: transform URLs into hyperlinks,
* convert smileys into images, etc.
*
* For performance reasons content is only filtered once; the result is stored
* in the cache table and retrieved from the cache the next time the same piece
@ -131,36 +46,37 @@
* caching for the entire format, not just for one filter.
*
* Beware of the filter cache when developing your module: it is advised to set
* your filter to 'cache' => FALSE while developing, but be sure to remove it
* again if it's not needed. You can clear the cache by running the SQL query
* 'DELETE * FROM cache_filter';
* your filter to 'cache' => FALSE while developing, but be sure to remove that
* setting if it's not needed, when you are no longer in development mode.
*
* @return
* An array of filter items. Each filter item has a unique name, prefixed
* with the name of the module that provides it. The item is an associative
* array that may contain the following key-value pairs:
* - 'title': (required) The administrative title of the filter.
* - 'description': A short, administrative description of what this filter
* does.
* - 'prepare callback': A callback function to call in the 'prepare' step
* of the filtering.
* - 'process callback': (required) The callback function to call in the
* 'process' step of the filtering.
* - 'settings callback': A callback function that provides form controls
* for the filter's settings. Each filter should apply either the default
* settings or the configured settings contained in $filter->settings. The
* user submitted values are stored in the database.
* - 'default settings': An array containing default settings for a filter to
* be applied when the filter has not been configured yet.
* - 'tips callback': A callback function that provides tips for using the
* filter. A module's tips should be informative and to the point. Short
* tips are preferably one-liners.
* - 'cache': Specifies whether the filtered text can be cached. TRUE by
* default. Note that defining FALSE makes the entire text format not
* An associative array of filters, whose keys are internal filter names,
* which should be unique and therefore prefixed with the name of the module.
* Each value is an associative array describing the filter, with the
* following elements (all are optional except as noted):
* - title: (required) An administrative summary of what the filter does.
* - description: Additional administrative information about the filter's
* behavior, if needed for clarification.
* - settings callback: The name of a function that returns configuration form
* elements for the filter. See hook_filter_FILTER_settings() for details.
* - default settings: An associative array containing default settings for
* the filter, to be applied when the filter has not been configured yet.
* - prepare callback: The name of a function that escapes the content before
* the actual filtering happens. See hook_filter_FILTER_prepare() for
* details.
* - process callback: (required) The name the function that performs the
* actual filtering. See hook_filter_FILTER_process() for details.
* - cache (default TRUE): Specifies whether the filtered text can be cached.
* Note that setting this to FALSE makes the entire text format not
* cacheable, which may have an impact on the site's overall performance.
* See filter_format_allowcache() for details.
* - tips callback: The name of a function that returns end-user-facing filter
* usage guidelines for the filter. See hook_filter_FILTER_tips() for
* details.
* - weight: A default weight for the filter in new text formats.
*
* For a detailed usage example, see filter_example.module. For an example of
* using multiple filters in one module, see filter_filter_info().
* @see filter_example.module
* @see hook_filter_info_alter()
*/
function hook_filter_info() {
$filters['filter_html'] = array(
@ -202,6 +118,164 @@ function hook_filter_info_alter(&$info) {
);
}
/**
* @} End of "addtogroup hooks".
*/
/**
* Settings callback for hook_filter_info().
*
* Note: This is not really a hook. The function name is manually specified via
* 'settings callback' in hook_filter_info(), with this recommended callback
* name pattern. It is called from filter_admin_format_form().
*
* This callback function is used to provide a settings form for filter
* settings, for filters that need settings on a per-text-format basis. This
* function should return the form elements for the settings; the filter
* module will take care of saving the settings in the database.
*
* If the filter's behavior depends on an extensive list and/or external data
* (e.g. a list of smileys, a list of glossary terms), then the filter module
* can choose to provide a separate, global configuration page rather than
* per-text-format settings. In that case, the settings callback function
* should provide a link to the separate settings page.
*
* @param $form
* The prepopulated form array of the filter administration form.
* @param $form_state
* The state of the (entire) configuration form.
* @param $filter
* The filter object containing the current settings for the given format,
* in $filter->settings.
* @param $format
* The format object being configured.
* @param $defaults
* The default settings for the filter, as defined in 'default settings' in
* hook_filter_info(). These should be combined with $filter->settings to
* define the form element defaults.
* @param $filters
* The complete list of filter objects that are enabled for the given format.
*
* @return
* An array of form elements defining settings for the filter. Array keys
* should match the array keys in $filter->settings and $defaults.
*/
function hook_filter_FILTER_settings($form, &$form_state, $filter, $format, $defaults, $filters) {
$filter->settings += $defaults;
$elements = array();
$elements['nofollow'] = array(
'#type' => 'checkbox',
'#title' => t('Add rel="nofollow" to all links'),
'#default_value' => $filter->settings['nofollow'],
);
return $elements;
}
/**
* Prepare callback for hook_filter_info().
*
* Note: This is not really a hook. The function name is manually specified via
* 'prepare callback' in hook_filter_info(), with this recommended callback
* name pattern. It is called from check_markup().
*
* See hook_filter_info() for a description of the filtering process. Filters
* should not use the 'prepare callback' step for anything other than escaping,
* because that would short-circuit the control the user has over the order in
* which filters are applied.
*
* @param $text
* The text string to be filtered.
* @param $filter
* The filter object containing settings for the given format.
* @param $format
* The text format object assigned to the text to be filtered.
* @param $langcode
* The language code of the text to be filtered.
* @param $cache
* A Boolean indicating whether the filtered text is going to be cached in
* {cache_filter}.
* @param $cache_id
* The ID of the filtered text in {cache_filter}, if $cache is TRUE.
*
* @return
* The prepared, escaped text.
*/
function hook_filter_FILTER_prepare($text, $filter, $format, $langcode, $cache, $cache_id) {
// Escape <code> and </code> tags.
$text = preg_replace('|<code>(.+?)</code>|se', "[codefilter_code]$1[/codefilter_code]", $text);
return $text;
}
/**
* Process callback for hook_filter_info().
*
* Note: This is not really a hook. The function name is manually specified via
* 'process callback' in hook_filter_info(), with this recommended callback
* name pattern. It is called from check_markup().
*
* See hook_filter_info() for a description of the filtering process. This step
* is where the filter actually transforms the text.
*
* @param $text
* The text string to be filtered.
* @param $filter
* The filter object containing settings for the given format.
* @param $format
* The text format object assigned to the text to be filtered.
* @param $langcode
* The language code of the text to be filtered.
* @param $cache
* A Boolean indicating whether the filtered text is going to be cached in
* {cache_filter}.
* @param $cache_id
* The ID of the filtered text in {cache_filter}, if $cache is TRUE.
*
* @return
* The filtered text.
*/
function hook_filter_FILTER_process($text, $filter, $format, $langcode, $cache, $cache_id) {
$text = preg_replace('|\[codefilter_code\](.+?)\[/codefilter_code\]|se', "<pre>$1</pre>", $text);
return $text;
}
/**
* Tips callback for hook_filter_info().
*
* Note: This is not really a hook. The function name is manually specified via
* 'tips callback' in hook_filter_info(), with this recommended callback
* name pattern. It is called from _filter_tips().
*
* A filter's tips should be informative and to the point. Short tips are
* preferably one-liners.
*
* @param $filter
* An object representing the filter.
* @param $format
* An object representing the text format the filter is contained in.
* @param $long
* Whether this callback should return a short tip to display in a form
* (FALSE), or whether a more elaborate filter tips should be returned for
* theme_filter_tips() (TRUE).
*
* @return
* Translated text to display as a tip.
*/
function hook_filter_FILTER_tips($filter, $format, $long) {
if ($long) {
return t('Lines and paragraphs are automatically recognized. The &lt;br /&gt; line break, &lt;p&gt; paragraph and &lt;/p&gt; close paragraph tags are inserted automatically. If paragraphs are not recognized simply add a couple blank lines.');
}
else {
return t('Lines and paragraphs break automatically.');
}
}
/**
* @addtogroup hooks
* @{
*/
/**
* Perform actions when a new text format has been created.
*

View File

@ -1195,22 +1195,24 @@ function filter_filter_info() {
* Settings callback for the HTML filter.
*/
function _filter_html_settings($form, &$form_state, $filter, $format, $defaults) {
$filter->settings += $defaults;
$settings['allowed_html'] = array(
'#type' => 'textfield',
'#title' => t('Allowed HTML tags'),
'#default_value' => isset($filter->settings['allowed_html']) ? $filter->settings['allowed_html'] : $defaults['allowed_html'],
'#default_value' => $filter->settings['allowed_html'],
'#maxlength' => 1024,
'#description' => t('A list of HTML tags that can be used. JavaScript event attributes, JavaScript URLs, and CSS are always stripped.'),
);
$settings['filter_html_help'] = array(
'#type' => 'checkbox',
'#title' => t('Display basic HTML help in long filter tips'),
'#default_value' => isset($filter->settings['filter_html_help']) ? $filter->settings['filter_html_help'] : $defaults['filter_html_help'],
'#default_value' => $filter->settings['filter_html_help'],
);
$settings['filter_html_nofollow'] = array(
'#type' => 'checkbox',
'#title' => t('Add rel="nofollow" to all links'),
'#default_value' => isset($filter->settings['filter_html_nofollow']) ? $filter->settings['filter_html_nofollow'] : $defaults['filter_html_nofollow'],
'#default_value' => $filter->settings['filter_html_nofollow'],
);
return $settings;
}
@ -1336,10 +1338,12 @@ function _filter_html_tips($filter, $format, $long = FALSE) {
* Settings callback for URL filter.
*/
function _filter_url_settings($form, &$form_state, $filter, $format, $defaults) {
$filter->settings += $defaults;
$settings['filter_url_length'] = array(
'#type' => 'textfield',
'#title' => t('Maximum link text length'),
'#default_value' => isset($filter->settings['filter_url_length']) ? $filter->settings['filter_url_length'] : $defaults['filter_url_length'],
'#default_value' => $filter->settings['filter_url_length'],
'#size' => 5,
'#maxlength' => 4,
'#field_suffix' => t('characters'),