filter_example.module 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. <?php
  2. /**
  3. * @file
  4. * Module file for filter_example.
  5. */
  6. /**
  7. * @defgroup filter_example Example: Filter
  8. * @ingroup examples
  9. * @{
  10. * Demonstrates the creation of filters.
  11. *
  12. * This is an example outlining how a module can be used to define a filter
  13. * to be run on user-submitted content before it is output to the browser.
  14. *
  15. * To show all the capabilities of the filter system, we will define two filters
  16. * in this module. One will substitute the string "foo" with an
  17. * administratively-defined replacement string. The other will find a custom
  18. * XML tag, <time />, and replace it by the current time.
  19. *
  20. * Foo filter
  21. *
  22. * Drupal has several content formats (they are not filters), and in our example
  23. * the foo replacement can be configured for each one of them, allowing an html
  24. * or php replacement, so the module includes a settings callback, with options
  25. * to configure that replacements. Also, a Tips callback will help showing the
  26. * current replacement for the content type being edited.
  27. *
  28. * Time filter.
  29. *
  30. * This filter is a little trickier to implement than the previous one.
  31. * Since the input involves special HTML characters (< and >) we have to
  32. * run the filter before HTML is escaped/stripped by other filters. But
  33. * we want to use HTML in our result as well, and so if we run this filter
  34. * first our replacement string could be escaped or stripped. The solution
  35. * is to use the "prepare" operation to escape the special characters, and
  36. * to later replace our escaped version in the "process" step.
  37. */
  38. /**
  39. * Implements hook_menu().
  40. */
  41. function filter_example_menu() {
  42. $items['examples/filter_example'] = array(
  43. 'title' => 'Filter Example',
  44. 'page callback' => '_filter_example_information',
  45. 'access callback' => TRUE,
  46. );
  47. return $items;
  48. }
  49. /**
  50. * Implements hook_help().
  51. */
  52. function filter_example_help($path, $arg) {
  53. switch ($path) {
  54. case 'admin/help#filter_example':
  55. return _filter_example_information();
  56. }
  57. }
  58. /**
  59. * Simply returns a little bit of information about the example.
  60. */
  61. function _filter_example_information() {
  62. return t("<p>This example provides two filters.</p><p>Foo Filter replaces
  63. 'foo' with a configurable replacement.</p><p>Time Tag replaces the string
  64. '&lt;time /&gt;' with the current time.</p><p>To use these filters, go to !link and
  65. configure an input format, or create a new one.</p>",
  66. array('!link' => l(t('admin/config/content/formats'), 'admin/config/content/formats'))
  67. );
  68. }
  69. /**
  70. * Implements hook_filter_info().
  71. *
  72. * Here we define the different filters provided by the module. For this
  73. * example, time_filter is a very static and simple replacement, but it requires
  74. * some preparation of the string because of the special html tags < and >. The
  75. * foo_filter is more complex, including its own settings and inline tips.
  76. */
  77. function filter_example_filter_info() {
  78. $filters['filter_foo'] = array(
  79. 'title' => t('Foo Filter (example)'),
  80. 'description' => t('Every instance of "foo" in the input text will be replaced with a preconfigured replacement.'),
  81. 'process callback' => '_filter_example_filter_foo_process',
  82. 'default settings' => array(
  83. 'filter_example_foo' => 'bar',
  84. ),
  85. 'settings callback' => '_filter_example_filter_foo_settings',
  86. 'tips callback' => '_filter_example_filter_foo_tips',
  87. );
  88. $filters['filter_time'] = array(
  89. 'title' => t('Time Tag (example)'),
  90. 'description' => t("Every instance of the special &lt;time /&gt; tag will be replaced with the current date and time in the user's specified time zone."),
  91. 'prepare callback' => '_filter_example_filter_time_prepare',
  92. 'process callback' => '_filter_example_filter_time_process',
  93. 'tips callback' => '_filter_example_filter_time_tips',
  94. );
  95. return $filters;
  96. }
  97. /*
  98. * Foo filter
  99. *
  100. * Drupal has several text formats (they are not filters), and in our example
  101. * the foo replacement can be configured for each one of them, so the module
  102. * includes a settings callback, with options to configure those replacements.
  103. * Also, a Tips callback will help showing the current replacement
  104. * for the content type being edited.
  105. */
  106. /**
  107. * Settings callback for foo filter.
  108. *
  109. * Make use of $format to have different replacements for every input format.
  110. * Since we allow the administrator to define the string that gets substituted
  111. * when "foo" is encountered, we need to provide an interface for this kind of
  112. * customization. The object format is also an argument of the callback.
  113. *
  114. * The settings defined in this form are stored in database by the filter
  115. * module, and they will be available in the $filter argument.
  116. */
  117. function _filter_example_filter_foo_settings($form, $form_state, $filter, $format, $defaults) {
  118. $settings['filter_example_foo'] = array(
  119. '#type' => 'textfield',
  120. '#title' => t('Substitution string'),
  121. '#default_value' => isset($filter->settings['filter_example_foo']) ? $filter->settings['filter_example_foo'] : $defaults['filter_example_foo'],
  122. '#description' => t('The string to substitute for "foo" everywhere in the text.'),
  123. );
  124. return $settings;
  125. }
  126. /**
  127. * Foo filter process callback.
  128. *
  129. * The actual filtering is performed here. The supplied text should be returned,
  130. * once any necessary substitutions have taken place. The example just replaces
  131. * foo with our custom defined string in the settings page.
  132. */
  133. function _filter_example_filter_foo_process($text, $filter, $format) {
  134. $replacement = isset($filter->settings['filter_example_foo']) ? $filter->settings['filter_example_foo'] : 'bar';
  135. return str_replace('foo', $replacement, $text);
  136. }
  137. /**
  138. * Filter tips callback for foo filter.
  139. *
  140. * The tips callback allows filters to provide help text to users during the
  141. * content editing process. Short tips are provided on the content editing
  142. * screen, while long tips are provided on a separate linked page. Short tips
  143. * are optional, but long tips are highly recommended.
  144. */
  145. function _filter_example_filter_foo_tips($filter, $format, $long = FALSE) {
  146. $replacement = isset($filter->settings['filter_example_foo']) ? $filter->settings['filter_example_foo'] : 'bar';
  147. if (!$long) {
  148. // This string will be shown in the content add/edit form.
  149. return t('<em>foo</em> replaced with %replacement.', array('%replacement' => $replacement));
  150. }
  151. else {
  152. return t('Every instance of "foo" in the input text will be replaced with a configurable value. You can configure this value and put whatever you want there. The replacement value is "%replacement".', array('%replacement' => $replacement));
  153. }
  154. }
  155. /**
  156. * Time filter prepare callback.
  157. *
  158. * We'll use [filter-example-time] as a replacement for the time tag.
  159. * Note that in a more complicated filter a closing tag may also be
  160. * required. For more information, see "Temporary placeholders and
  161. * delimiters" at http://drupal.org/node/209715.
  162. */
  163. function _filter_example_filter_time_prepare($text, $filter) {
  164. return preg_replace('!<time ?/>!', '[filter-example-time]', $text);
  165. }
  166. /**
  167. * Time filter process callback.
  168. *
  169. * Now, in the "process" step, we'll search for our escaped time tags and
  170. * do the real filtering: replace the xml tag with the date.
  171. */
  172. function _filter_example_filter_time_process($text, $filter) {
  173. return str_replace('[filter-example-time]', '<em>' . format_date(time()) . '</em>', $text);
  174. }
  175. /**
  176. * Filter tips callback for time filter.
  177. *
  178. * The tips callback allows filters to provide help text to users during the
  179. * content editing process. Short tips are provided on the content editing
  180. * screen, while long tips are provided on a separate linked page. Short tips
  181. * are optional, but long tips are highly recommended.
  182. */
  183. function _filter_example_filter_time_tips($filter, $format, $long = FALSE) {
  184. return t('<em>&lt;time /&gt;</em> is replaced with the current time.');
  185. }
  186. /**
  187. * @} End of "defgroup filter_example".
  188. */