You are here

STYLE_PLUGINS.txt in Openlayers 6.2

Current for 6.x-2.x

Style plugins are code snippets providing style context
callbacks to OpenLayers styles.

Such callbacks (written in JavaScript) are needed to provide
styling which is dependent on characteristics which are not
known at time of PHP rendering.

A common example is changing pointRadius style property based
on the number of features taking place in a cluster, whereas
clustering is performed by JavaScript and so cluster composition
changes w/out PHP being invoked.

# Creating a new OpenLayers Style Plugin from Scratch

First, you'll need to create a module. Of course, skip through this step if
there's already a module that exists to which this style plugin will be added.
But if not, create a file called `modulename.info` with the contents

    core = "6.x"
    dependencies[] = "openlayers"
    name = "modulename"
    package = "OpenLayers"
    project = "modulename"

Then you'll want to register your style plugins.

## Registering plugins directory

This is done implementing `hook_ctools_plugin_directory'
and `hook_ctools_plugin_api'.

Since your module is called `modulename', their implementation would be:

  function modulename_ctools_plugin_api($module, $api) {
    // Define plugins for OpenLayers plugins api
    if ($module == "openlayers") {
      switch ($api) {
        case 'openlayers_styles':
          return array('version' => 1);
      }
    }
  }

  function modulename_ctools_plugin_directory($module, $plugin) {
    if ($module == 'openlayers' && $plugin == 'style_plugin') {
      return 'plugins/style_plugin';
    }
  }

At that point you can put actual plugins, one file per plugin,
in the `plugins/style_plugin' directory, or whatever you returned
from the `hook_ctools_plugin_directory' implementation. 

## Writing the minimal PHP side of plugin

A plugin file starts with a plugin definition, like the
following:

  // Define plugin for CTools
  $plugin = array(
    'title' => t('My style plugin title'),
    'description' => t('What this plugin does'),
    'style_plugin' => array(
      'class' => 'modulename_pluginname', // <-- NOTE!
      'parent' => 'openlayers_style_plugin',
    ),
  );

The above definition says that the plugin is implemented by
the `modulename_pluginname' class (see NOTE above), which is
a subclass of `openlayers_style_plugin`. We implement that next:


  class modulename_pluginname extends openlayers_style_plugin {

    // Advertise which style properties we expose support for,
    // and which callback to use for each one
    function get_context_properties() {
      return array(
        'label' => 'getLabel' // <-- NOTE !
      );
    }

    // Send the JS file containing the JavaScript side
    // implementation of the plugin.
    function render() {
      drupal_add_js(drupal_get_path('module', 'modulename') .
        '/plugins/style_plugin/modulename_pluginname.js');
    }

  }

The above definition provides NO parameters to the actual context
callback function. We'll see how to add configurability later.
For now let's move on to the JavaScript side.

## Writing the JavaScript side of plugin

The OpenLayers module renderer will expect to find a
Drupal.openlayers.style_plugins.<modulename_pluginname>
Javascript class, as specified by the 'class' attribute of
the 'style_plugin' array in the PHP plugin definition.

The JavaScript side of style plugin will be put in the file
referenced by the render() function of the PHP part, and will need
to provide this class. As with the following example:

 // Define the class constructor
 Drupal.openlayers.style_plugin.modulename_pluginname = function (params) {
   this.params = params;
 };

Note that the constructor can take parameters, which the PHP side
of the style plugin can export to let user configure the style plugin.
We'll see this later.

In addition to the constructor, the Drupal OpenLayers module (`DOL',
from now on) will also expect to find the callbacks advertised
by the `get_context_properties` function of the PHP side of the style
plugin. We'll need to provide those as well. They can be defined
in the class prototype:

  // Style plugin class prototype
 Drupal.openlayers.style_plugin.modulename_pluginname.prototype = {

   // Style context function
   'getLabel' : function(feature) {
      return feature.attributes.length;
   }

 }

## Providing configurability of style plugin

The PHP side of code can provide a configuration form for the plugin.
As you saw above, the JavaScript class constructor will be passed
configuration parameters. These parameters you can define from
the PHP side, defining an options_form() and optionally an
options_init() method. Example:

  function options_init() {
    return array(
      'feature_weight' => 2,
      'point_radius_min' => 6,
      'point_radius_max' => 12,
    );
  }

  function options_form($defaults = array()) {
    $form = array();

    $form['point_radius_min'] = array(
      '#type' => 'textfield',
      '#title' => t('Min radius'),
      '#description' => t('Minimum value for the point radius.'),
      '#default_value' => isset($defaults['point_radius_min']) ?
        $defaults['point_radius_min'] : 6,
    );
    $form['point_radius_max'] = array(
      '#type' => 'textfield',
      '#title' => t('Max radius'),
      '#description' => t('Maximum value for the point radius.'),
      '#default_value' => isset($defaults['point_radius_max']) ?
        $defaults['point_radius_max'] : 12,
    );
    $form['feature_weight'] = array(
      '#type' => 'textfield',
      '#title' => t('Feature weight'),
      '#description' => t('Weight of each additional feature for the final point
 radius.'),
      '#default_value' => isset($defaults['feature_weight']) ?
        $defaults['feature_weight'] : 2,
    );

    return $form;
  }

File

docs/STYLE_PLUGINS.txt
View source
  1. Current for 6.x-2.x
  2. Style plugins are code snippets providing style context
  3. callbacks to OpenLayers styles.
  4. Such callbacks (written in JavaScript) are needed to provide
  5. styling which is dependent on characteristics which are not
  6. known at time of PHP rendering.
  7. A common example is changing pointRadius style property based
  8. on the number of features taking place in a cluster, whereas
  9. clustering is performed by JavaScript and so cluster composition
  10. changes w/out PHP being invoked.
  11. # Creating a new OpenLayers Style Plugin from Scratch
  12. First, you'll need to create a module. Of course, skip through this step if
  13. there's already a module that exists to which this style plugin will be added.
  14. But if not, create a file called `modulename.info` with the contents
  15. core = "6.x"
  16. dependencies[] = "openlayers"
  17. name = "modulename"
  18. package = "OpenLayers"
  19. project = "modulename"
  20. Then you'll want to register your style plugins.
  21. ## Registering plugins directory
  22. This is done implementing `hook_ctools_plugin_directory'
  23. and `hook_ctools_plugin_api'.
  24. Since your module is called `modulename', their implementation would be:
  25. function modulename_ctools_plugin_api($module, $api) {
  26. // Define plugins for OpenLayers plugins api
  27. if ($module == "openlayers") {
  28. switch ($api) {
  29. case 'openlayers_styles':
  30. return array('version' => 1);
  31. }
  32. }
  33. }
  34. function modulename_ctools_plugin_directory($module, $plugin) {
  35. if ($module == 'openlayers' && $plugin == 'style_plugin') {
  36. return 'plugins/style_plugin';
  37. }
  38. }
  39. At that point you can put actual plugins, one file per plugin,
  40. in the `plugins/style_plugin' directory, or whatever you returned
  41. from the `hook_ctools_plugin_directory' implementation.
  42. ## Writing the minimal PHP side of plugin
  43. A plugin file starts with a plugin definition, like the
  44. following:
  45. // Define plugin for CTools
  46. $plugin = array(
  47. 'title' => t('My style plugin title'),
  48. 'description' => t('What this plugin does'),
  49. 'style_plugin' => array(
  50. 'class' => 'modulename_pluginname', // <-- NOTE!
  51. 'parent' => 'openlayers_style_plugin',
  52. ),
  53. );
  54. The above definition says that the plugin is implemented by
  55. the `modulename_pluginname' class (see NOTE above), which is
  56. a subclass of `openlayers_style_plugin`. We implement that next:
  57. class modulename_pluginname extends openlayers_style_plugin {
  58. // Advertise which style properties we expose support for,
  59. // and which callback to use for each one
  60. function get_context_properties() {
  61. return array(
  62. 'label' => 'getLabel' // <-- NOTE !
  63. );
  64. }
  65. // Send the JS file containing the JavaScript side
  66. // implementation of the plugin.
  67. function render() {
  68. drupal_add_js(drupal_get_path('module', 'modulename') .
  69. '/plugins/style_plugin/modulename_pluginname.js');
  70. }
  71. }
  72. The above definition provides NO parameters to the actual context
  73. callback function. We'll see how to add configurability later.
  74. For now let's move on to the JavaScript side.
  75. ## Writing the JavaScript side of plugin
  76. The OpenLayers module renderer will expect to find a
  77. Drupal.openlayers.style_plugins.
  78. Javascript class, as specified by the 'class' attribute of
  79. the 'style_plugin' array in the PHP plugin definition.
  80. The JavaScript side of style plugin will be put in the file
  81. referenced by the render() function of the PHP part, and will need
  82. to provide this class. As with the following example:
  83. // Define the class constructor
  84. Drupal.openlayers.style_plugin.modulename_pluginname = function (params) {
  85. this.params = params;
  86. };
  87. Note that the constructor can take parameters, which the PHP side
  88. of the style plugin can export to let user configure the style plugin.
  89. We'll see this later.
  90. In addition to the constructor, the Drupal OpenLayers module (`DOL',
  91. from now on) will also expect to find the callbacks advertised
  92. by the `get_context_properties` function of the PHP side of the style
  93. plugin. We'll need to provide those as well. They can be defined
  94. in the class prototype:
  95. // Style plugin class prototype
  96. Drupal.openlayers.style_plugin.modulename_pluginname.prototype = {
  97. // Style context function
  98. 'getLabel' : function(feature) {
  99. return feature.attributes.length;
  100. }
  101. }
  102. ## Providing configurability of style plugin
  103. The PHP side of code can provide a configuration form for the plugin.
  104. As you saw above, the JavaScript class constructor will be passed
  105. configuration parameters. These parameters you can define from
  106. the PHP side, defining an options_form() and optionally an
  107. options_init() method. Example:
  108. function options_init() {
  109. return array(
  110. 'feature_weight' => 2,
  111. 'point_radius_min' => 6,
  112. 'point_radius_max' => 12,
  113. );
  114. }
  115. function options_form($defaults = array()) {
  116. $form = array();
  117. $form['point_radius_min'] = array(
  118. '#type' => 'textfield',
  119. '#title' => t('Min radius'),
  120. '#description' => t('Minimum value for the point radius.'),
  121. '#default_value' => isset($defaults['point_radius_min']) ?
  122. $defaults['point_radius_min'] : 6,
  123. );
  124. $form['point_radius_max'] = array(
  125. '#type' => 'textfield',
  126. '#title' => t('Max radius'),
  127. '#description' => t('Maximum value for the point radius.'),
  128. '#default_value' => isset($defaults['point_radius_max']) ?
  129. $defaults['point_radius_max'] : 12,
  130. );
  131. $form['feature_weight'] = array(
  132. '#type' => 'textfield',
  133. '#title' => t('Feature weight'),
  134. '#description' => t('Weight of each additional feature for the final point
  135. radius.'),
  136. '#default_value' => isset($defaults['feature_weight']) ?
  137. $defaults['feature_weight'] : 2,
  138. );
  139. return $form;
  140. }