Ready to watch this entire course?
Become a member and get unlimited access to the entire skills library of over 4,900 courses, including more Developer and personalized recommendations.Start Your Free Trial Now
- View Offline
- Creating your first module
- Interacting with hooks
- Working with permissions and roles
- Controlling access
- Adding a menu item to an admin interface
- Using the Form API (FAPI) to quickly create a form
- Creating custom form validation
- Manually creating a custom content type
- Validating user input
- Importing content using feeds
- Creating a block
- Understanding best practices and coding standards
Skill Level Advanced
I imported wind farms from the Open Energy Information Initiative and I can now view each node of content type wind farm. I hid the latitude and longitude because there was no need to show it to the user in this context. However, this view is uninteresting. Having a map with a marker indicating where the wind farm is has a positive impact on the user. To do this, I'm going to inject an element into the full view of the node and make a custom function for displaying the element. By providing this functionality within the custom module, I am allowing themers to override or customize the base functionality I provided.
I search the contributed modules and found GMap3 Tools, a module that allows a developer to quickly add a Google Map by providing an API made explicitly for Drupal. It's minimal and functional so it fulfills my needs. Open the IDE and then go to windfarms.module and navigate to the end. The first thing I will do is implement hook_node_ view, which acts on the node that is being assembled before rendering, hook_node_view, function windfarms_node_view takes three parameters, the node, the view_mode and the language code.
This function will be accessed on every node view, so unless I give it context, it's going to try to put a map on every page. I only want to put the map on the full view of the windfarm content type. If ($node-> type == 'windfarm' && $view_mode == 'full'. When rendering a node, Drupal builds a structured array keyed with the element name. This markup is in the same structure as the form API and is placed in the content property of the node.
I'm going to create a new element called windfarm_ gmap in the content property, $node->content and as this is a structured array, I will access it by key 'windfarm_gmap' = array. I'm going to use hash tag markup to indicate that the contents of this element are just pre-rendered HTML. I'm going to call the theme function to create the contents. The theme function generates themed output by examining what was requested and determines what is the right theming option or template.
Theme takes two parameters: the name of the hook, then an optional array of parameters that will be passed to the theming target. I'm going to create a theme function for windfarm_ gmap, so I'll stick with the name, and I'll pass the node itself to the theme function with key node. Weight is used to determine the order in which something is displayed. The higher the weight, the heavier it is and heavy things sink. Weight is used in the form API and menu API among other places. In this context, I'm going to use weight to ensure that the Google Map is the last thing to be shown by setting it to the maximum 100, so #weight is 100.
The next thing I need to do is tell Drupal about the custom theme function and the arguments it takes. I'll do that by implementing hook theme which registers the custom themes with Drupal. Hook_theme takes four parameters: function windfarms_theme, existing, type, theme and path.
I won't actually need any of them for what I'm doing, but as they required by the hook, I must define them. Hook_theme returns an array keyed by the name of the theme function and some options. I need to specify that variables will be made available to the theme function, so I'll provide the structure; return array containing windfarm_ gmap and a nested array, specify the variables which will just be the node which will default to null.
Now that the hook_theme has been implemented, let's create the theme function itself. Theme functions don't implement anything, hooks are otherwise. They just return a string with the output. Start with a doc block, Wind Farm Google Map theme function. By naming convention, theme functions must start with theme_windfarm_gmap which takes variables the array that was created earlier.
Let's get some introspection into variables, dpm($ variables), save to file, then go back to the browser. Drupal's theme registry, the internal structure for determining what themes what, is heavily cached to improve site performance, therefore the cache will need to be cleared in order to see the changes. Go to Configuration > Development and click on Performance, so you can clear all caches.
Go back to the homepage and view one of the Wind Farms nodes. Now there's debugging information shown at the top of the page as an array with one element node. The title is shown as is, but the body, latitude and longitude are the nested arrays with the language undefined. Now that I know what the structure of the node is, I can access those elements to add the Google Map. Return to the IDE and remove the debugging information.
The first thing that needs to be done is to check if the Google Map has been enabled in the admin interface. If not, just return. Check to see if the Google Map is enabled; if not variable_get and the name is windfarms_gmap; if not, then just return. Next, I'll check to see if I have the right information needed to display the map. In particular, both latitude and longitude are needed, so $lat = $variables 'node'. I'm going to access windfarm_latitude, LANGUAGE_NONE, 0 and then 'value'.
The longitude will be just about the same, add a comment, Cannot render map without both latitude and longitude, if lat is equal to the empty string or long is equal to the empty string, then return.
Now that I'm confident that I have all the context needed, I can start building the map using the GMap3 Tools module. Three basic steps are needed. First, load the include file, second create the map with the configuration array, then third, add the element that will be populated with the map by ID. First, I'll include the module using the Drupal function module_load_include, which loads the module include file. It takes the file extension, the name of the module and optionally the base filename.
So module_load_include, and let's include file and module is gmap3_tools. I'm going to need two more things from the windfarm node, the facility name and the description which I will use to populate the marker on the map. As this is user supplied input, I don't trust it, as it may contain content other than plain text, which will at best possibly break the map and at worse, contain malicious code.
Drupal provides mechanism for encoding special characters in a plain text string for HTML display using the function check_plain which takes the string as a parameter and returns the sanitized result, $facility_ name = check_plain ($variables 'node' -> title); $description = check_plain (variables 'node' -> body, LANGUAGE_NONE, 0 and then the key 'value'.
The next one will be the mapTypeId where I will specify the use of a satellite map rather than a roadmap, so the windfarm can be actually seen, GMAP3_TOOLS_MAP_TYPE_ID_SATELLITE. To add a marker to the map, set markers to an array populated with a helper function gmap3_tools_create_marker, which takes four parameters, the latitude, the longitude, the title, which I will set to the facility name and the content which I will set as the description.
I'll set the width to 500 pixels and the height to 400 pixels and then close the div. Finally, return the theme output, save, then return to the browser and refresh the page. The Google Map has now shown with a marker, hovering will show a title and clicking will show the description. Now that I've added a Google Map to the node view, I'd like to create a map that shows a number of wind farms on a map that allows you to get more information about them.