diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/filter/filter.api.php | 328 | ||||
-rw-r--r-- | modules/filter/filter.module | 12 |
2 files changed, 209 insertions, 131 deletions
diff --git a/modules/filter/filter.api.php b/modules/filter/filter.api.php index 399d564a1..ca01eec44 100644 --- a/modules/filter/filter.api.php +++ b/modules/filter/filter.api.php @@ -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. - * - * 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. + * 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 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. - * - * 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() + * HTML and change it. For many filters, the prepare step is not necessary. * - * '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( @@ -203,6 +119,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 <br /> line break, <p> paragraph and </p> 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. * * @param $format diff --git a/modules/filter/filter.module b/modules/filter/filter.module index 7babfc65f..0c0867a12 100644 --- a/modules/filter/filter.module +++ b/modules/filter/filter.module @@ -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'), |