You are here

BEHAVIORS.txt in Openlayers 6.2

Same filename and directory in other branches
  1. 7.2 docs/BEHAVIORS.txt
Current for 6.x-2.0-alpha6


# Creating a new OpenLayers Behavior 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 behavior 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"

In this case, you're creating a module just for this feature. So you'll need to
implement a hook to notify OpenLayers that your module can do something for it.
There's a hook called `hook_openlayers_behaviors` for this, and since your
module is called modulename, its implementation should be
`modulename_openlayers_behaviors`. A basic implementation would be

    function modulename_openlayers_behaviors() {
      return array(
        'openlayers_behavior_mybehavior' => array(
          'title' => t('My Behavior'),
          'description' => t('Does something'),
          'type' => 'layer',
          'path' => drupal_get_path('module', 'modulename')
            .'/includes/behaviors',
          'file' => 'openlayers_behavior_mybehavior.inc',
          'behavior' => array(
            'class' => 'openlayers_behavior_mybehavior',
            'parent' => 'openlayers_behavior',
          ),
        ),
      );
    }

Note the essentials here: this tells the OpenLayers module that there is a file
in `modules/modulename/includes/behaviors/` which implements a class called
`openlayers_behavior_mybehavior`. It isn't strictly necessary to create an
includes folder and a behaviors folder under it, but it's good practice so that
your module doesn't become cluttered.

So on to the PHP that this hook refers to: usually there's only a small amount
of PHP written for each behavior. On the first level, the file simply must
include a class that extends the class openlayers_behavior:

    class openlayers_behavior_mybehavior extends openlayers_behavior {}

There'll be a little bit for this one, but it's not very functional - only
adding JavaScript code and declaring forms.

Here's what you'll write for this behavior:

    class openlayers_behavior_mybehavior extends openlayers_behavior {}

      function options_init() {
        return array(
        );
      }
    
      function options_form($defaults) {
        return array(
          'filteredlayer' => array(
            '#type' => 'select',
            '#options' => $this->map['layers'],
            '#description' => t('Select layer to filter'),
            '#default_value' => isset($defaults['filteredlayer']) ? 
              $defaults['filteredlayer'] : NULL
          ),
        );
      }
    
      function render(&$map) {
        drupal_add_js(drupal_get_path('module', 'mybehavior') 
          .'/includes/behaviors/js/openlayers_behavior_mybehavior.js');
        return $this->options;
      }
    }

As you can see, there's an options_form method which is called when the list of
behaviors is generated for each preset, and given a `$defaults` array if there
have already been values saved. It isn't required to implement this method,
although many behaviors will need it. And at this level - in the options_form,
you have access to the preset/map with $this - so you can get layers, styles,
and other parts of the preset to play around with The `render(&$map)` function
is indeed required, since it is called for every behavior.

There's quite a bit of Javascript to write for this behavior:

    /**
     * Maptimeline Behavior
     */
    Drupal.behaviors.openlayers_behavior_mybehavior = function(context) {

      var data = $(context).data('openlayers');
      var slider_div = {};
      if (data && data.map.behaviors['openlayers_behavior_mybehavior']) {
        behavior = data.map.behaviors['openlayers_behavior_mybehavior'];
        layer = data.openlayers.getLayersBy(
          'drupalID', 
          behavior.filteredlayer)[0];
          // Do things with this feature, etc.
        });
      }
    }

Note the essentials of this file: all of the functionality needed is contained
in a single function, `Drupal.behaviors.openlayers_behavior_mybehavior`. The
facts that the containing function is called `openlayers_behavior_mybehavior`
and that it receives a single argument, `context`, are essential, but besides
those restrictions, behaviors can contain any Javascript code whatsoever.
Behaviors are called after all layers and styles are added to the map and the
map is rendered.

This code demonstrates a few core concepts of behavior-writing:

* The OpenLayers [Map object](http://dev.openlayers.org/releases/OpenLayers-2.8/doc/apidocs/files/OpenLayers/Map-js.html)
  is accessible via `$(context).data('openlayers').openlayers`
* The [jQuery Data function](http://api.jquery.com/jQuery.data/) is used in the 
  OpenLayers module to simplify variable scope and avoid the possibility of
  memory leaks.

File

docs/BEHAVIORS.txt
View source
  1. Current for 6.x-2.0-alpha6
  2. # Creating a new OpenLayers Behavior from Scratch
  3. First, you'll need to create a module. Of course, skip through this step if
  4. there's already a module that exists to which this behavior will be added. But
  5. if not, create a file called `modulename.info` with the contents
  6. core = "6.x"
  7. dependencies[] = "openlayers"
  8. name = "modulename"
  9. package = "OpenLayers"
  10. project = "modulename"
  11. In this case, you're creating a module just for this feature. So you'll need to
  12. implement a hook to notify OpenLayers that your module can do something for it.
  13. There's a hook called `hook_openlayers_behaviors` for this, and since your
  14. module is called modulename, its implementation should be
  15. `modulename_openlayers_behaviors`. A basic implementation would be
  16. function modulename_openlayers_behaviors() {
  17. return array(
  18. 'openlayers_behavior_mybehavior' => array(
  19. 'title' => t('My Behavior'),
  20. 'description' => t('Does something'),
  21. 'type' => 'layer',
  22. 'path' => drupal_get_path('module', 'modulename')
  23. .'/includes/behaviors',
  24. 'file' => 'openlayers_behavior_mybehavior.inc',
  25. 'behavior' => array(
  26. 'class' => 'openlayers_behavior_mybehavior',
  27. 'parent' => 'openlayers_behavior',
  28. ),
  29. ),
  30. );
  31. }
  32. Note the essentials here: this tells the OpenLayers module that there is a file
  33. in `modules/modulename/includes/behaviors/` which implements a class called
  34. `openlayers_behavior_mybehavior`. It isn't strictly necessary to create an
  35. includes folder and a behaviors folder under it, but it's good practice so that
  36. your module doesn't become cluttered.
  37. So on to the PHP that this hook refers to: usually there's only a small amount
  38. of PHP written for each behavior. On the first level, the file simply must
  39. include a class that extends the class openlayers_behavior:
  40. class openlayers_behavior_mybehavior extends openlayers_behavior {}
  41. There'll be a little bit for this one, but it's not very functional - only
  42. adding JavaScript code and declaring forms.
  43. Here's what you'll write for this behavior:
  44. class openlayers_behavior_mybehavior extends openlayers_behavior {}
  45. function options_init() {
  46. return array(
  47. );
  48. }
  49. function options_form($defaults) {
  50. return array(
  51. 'filteredlayer' => array(
  52. '#type' => 'select',
  53. '#options' => $this->map['layers'],
  54. '#description' => t('Select layer to filter'),
  55. '#default_value' => isset($defaults['filteredlayer']) ?
  56. $defaults['filteredlayer'] : NULL
  57. ),
  58. );
  59. }
  60. function render(&$map) {
  61. drupal_add_js(drupal_get_path('module', 'mybehavior')
  62. .'/includes/behaviors/js/openlayers_behavior_mybehavior.js');
  63. return $this->options;
  64. }
  65. }
  66. As you can see, there's an options_form method which is called when the list of
  67. behaviors is generated for each preset, and given a `$defaults` array if there
  68. have already been values saved. It isn't required to implement this method,
  69. although many behaviors will need it. And at this level - in the options_form,
  70. you have access to the preset/map with $this - so you can get layers, styles,
  71. and other parts of the preset to play around with The `render(&$map)` function
  72. is indeed required, since it is called for every behavior.
  73. There's quite a bit of Javascript to write for this behavior:
  74. /**
  75. * Maptimeline Behavior
  76. */
  77. Drupal.behaviors.openlayers_behavior_mybehavior = function(context) {
  78. var data = $(context).data('openlayers');
  79. var slider_div = {};
  80. if (data && data.map.behaviors['openlayers_behavior_mybehavior']) {
  81. behavior = data.map.behaviors['openlayers_behavior_mybehavior'];
  82. layer = data.openlayers.getLayersBy(
  83. 'drupalID',
  84. behavior.filteredlayer)[0];
  85. // Do things with this feature, etc.
  86. });
  87. }
  88. }
  89. Note the essentials of this file: all of the functionality needed is contained
  90. in a single function, `Drupal.behaviors.openlayers_behavior_mybehavior`. The
  91. facts that the containing function is called `openlayers_behavior_mybehavior`
  92. and that it receives a single argument, `context`, are essential, but besides
  93. those restrictions, behaviors can contain any Javascript code whatsoever.
  94. Behaviors are called after all layers and styles are added to the map and the
  95. map is rendered.
  96. This code demonstrates a few core concepts of behavior-writing:
  97. * The OpenLayers [Map object](http://dev.openlayers.org/releases/OpenLayers-2.8/doc/apidocs/files/OpenLayers/Map-js.html)
  98. is accessible via `$(context).data('openlayers').openlayers`
  99. * The [jQuery Data function](http://api.jquery.com/jQuery.data/) is used in the
  100. OpenLayers module to simplify variable scope and avoid the possibility of
  101. memory leaks.