filter_example.module

  1. examples
    1. 6 filter_example/filter_example.module
    2. 7 filter_example/filter_example.module
    3. 8 filter_example/filter_example.module
  2. drupal
    1. 4.6 developer/examples/filter_example.module
    2. 4.7 developer/examples/filter_example.module
    3. 5 developer/examples/filter_example.module

This is an example outlining how a module can be used to define a filter to be run on user-submitted content before it is output to the browser.

To show all the capabilities of the filter system, we will define two filters in this module. One will substitute the string "foo" with an administratively- defined replacement string. The other will find a custom XML tag, <time />, and replace it by the current time.

Functions & methods

NameDescription
filter_example_filterImplementation of hook_filter().
filter_example_filter_tipsImplementation of hook_filter_tips().
filter_example_helpImplementation of hook_help().

File

developer/examples/filter_example.module
View source
  1. <?php
  2. /**
  3. * @file
  4. * This is an example outlining how a module can be used to define a filter
  5. * to be run on user-submitted content before it is output to the browser.
  6. *
  7. * To show all the capabilities of the filter system, we will define two filters
  8. * in this module. One will substitute the string "foo" with an administratively-
  9. * defined replacement string. The other will find a custom XML tag, <time />, and
  10. * replace it by the current time.
  11. */
  12. /**
  13. * Implementation of hook_help().
  14. *
  15. * Throughout Drupal, hook_help() is used to display help text at the top of
  16. * pages. Some other parts of drupal pages get explanatory text from these hooks
  17. * as well. We use it here to provide a description of the module on the
  18. * module administration page.
  19. */
  20. function filter_example_help($section) {
  21. switch ($section) {
  22. case 'admin/modules#description':
  23. // This description is shown in the listing at admin/modules.
  24. return t('An example module showing how to define a custom filter.');
  25. }
  26. }
  27. /**
  28. * Implementation of hook_filter_tips().
  29. *
  30. * This hook allows filters to provide help text to users during the content
  31. * editing process. Short tips are provided on the content editing screen, while
  32. * long tips are provided on a separate linked page. Short tips are optional,
  33. * but long tips are highly recommended.
  34. */
  35. function filter_example_filter_tips($delta, $format, $long = FALSE) {
  36. switch ($delta) {
  37. case 0:
  38. if ($long) {
  39. return t('Every instance of "foo" in the input text will be replaced with "%replacement".', array('%replacement' => variable_get('filter_example_foo_'. $format, 'bar')));
  40. }
  41. break;
  42. case 1:
  43. if ($long) {
  44. return 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.');
  45. }
  46. else {
  47. return t('Use &lt;time /&gt; to display the current date/time.');
  48. }
  49. break;
  50. }
  51. }
  52. /**
  53. * Implementation of hook_filter().
  54. *
  55. * The bulk of filtering work is done here. This hook is quite complicated, so
  56. * we'll discuss each operation it defines.
  57. */
  58. function filter_example_filter($op, $delta = 0, $format = -1, $text = '') {
  59. // The "list" operation provides the module an opportunity to declare both how
  60. // many filters it defines and a human-readable name for each filter. Note that
  61. // the returned name should be passed through t() for translation.
  62. if ($op == 'list') {
  63. return array(
  64. 0 => t('Substitute "foo"'),
  65. 1 => t('Current time'));
  66. }
  67. // All operations besides "list" provide a $delta argument so we know which
  68. // filter they refer to. We'll switch on that argument now so that we can
  69. // discuss each filter in turn.
  70. switch ($delta) {
  71. // First we define the simple string substitution filter.
  72. case 0:
  73. switch ($op) {
  74. // This description is shown in the administrative interface, unlike the
  75. // filter tips which are shown in the content editing interface.
  76. case 'description':
  77. return t('Substitutes a custom string for the string "foo" in the text.');
  78. // We don't need the "prepare" operation for this filter, but it's required
  79. // to at least return the input text as-is.
  80. case 'prepare':
  81. return $text;
  82. // The actual filtering is performed here. The supplied text should be
  83. // returned, once any necessary substitutions have taken place.
  84. case 'process':
  85. return str_replace('foo', variable_get("filter_example_foo_$format", 'bar'), $text);
  86. // Since we allow the administrator to define the string that gets
  87. // substituted when "foo" is encountered, we need to provide an
  88. // interface for this customization. Note that the value of $format
  89. // needs to be provided as part of the form name, so that different
  90. // customization can be done for this filter in each of the different
  91. // input formats that may use it.
  92. case 'settings':
  93. $form['filter_example'] = array(
  94. '#type' => 'fieldset',
  95. '#title' => t('Foo filter'),
  96. '#collapsible' => TRUE,
  97. '#collapsed' => TRUE,
  98. );
  99. $form['filter_example']["filter_example_foo_$format"] = array(
  100. '#type' => 'textfield',
  101. '#title' => t('Substitution string'),
  102. '#default_value' => variable_get("filter_example_foo_$format", 'bar'),
  103. '#description' => t('The string to substitute for "foo" everywhere in the text.')
  104. );
  105. return $form;
  106. }
  107. break;
  108. // Next is our "time tag" filter.
  109. case 1:
  110. switch ($op) {
  111. // This description is shown in the administrative interface, unlike the
  112. // filter tips which are shown in the content editing interface.
  113. case 'description':
  114. return t('Inserts the current time in the place of a &lt;time /&gt; tags.');
  115. // Since this filter will return a different result on each page load, we
  116. // need to return TRUE for "no cache" to ensure that the filter is run
  117. // every time the text is requested.
  118. case 'no cache':
  119. return TRUE;
  120. // This filter is a little trickier to implement than the previous one.
  121. // Since the input involves special HTML characters (< and >) we have to
  122. // run the filter before HTML is escaped/stripped by other filters. But
  123. // we want to use HTML in our result as well, and so if we run this filter
  124. // first our replacement string could be escaped or stripped. The solution
  125. // is to use the "prepare" operation to escape the special characters, and
  126. // to later replace our escaped version in the "process" step.
  127. //
  128. // We'll use the bytes 0xFE and 0xFF to replace < and > here. These bytes
  129. // are not valid in UTF-8 data and thus unlikely to cause problems.
  130. case 'prepare':
  131. return preg_replace('!<time ?/>!', '\xFEtime /\xFF', $text);
  132. // Now, in the "process" step, we'll search for our escaped time tags and
  133. // to the real filtering.
  134. case 'process':
  135. return str_replace('\xFEtime /\xFF', '<em>'. format_date(time()) .'</em>', $text);
  136. }
  137. break;
  138. }
  139. }
Login or register to post comments