Submitted by Jordan on
I recently had to adjust the output from a field on a page. Here's how I did it.
There are some excellent articles and even instructional videos on how to override templates for things in Drupal - pages, content types, even individual fields. But everything I found described how to alter the html wrapper around the field item, and said nothing about how to alter the field output itself.
The Challenge
For example: Let's say I've got some geolocation data. I have stored latitude and longitude and the field is set to output as a geofield map. But let's say I want to take that data and output it as a static map instead.
There's A Module For That
Of course there is. You could use the geofield with staticmap modules. But those are both community-contributed modules with few recent updates and little third-party support. I found several patches that hadn't even been reviewed & tested by the community. Naturally, the modules didn't work for me.
Note: I deeply appreciate the efforts of other community developers. I'm a contrib module author myself and I respect how much effort it takes to publish a module, nonetheless support it. Many modules are reliant on client funding. In addition, if the community refuses to review a patch, the module maintainer can hardly be blamed for that. All I'm saying is that these appear to be fringe cases that don't get the necessary support from the community as a whole.
Roll Up Your Sleeves
Time to roll a custom template. This will probably go in your theme directory. (One exception would be if you have a custom module and want to use it to modify the output of a field.)
Template files follow a naming convention. For a field, it's "field--your_field_here.tpl.php." In my case, it was field--field_location_computed.tpl.php. Notes:
- There are two dashes after "field" and before your field name.
- Your field name is the machine name for your field. See Admin > Structure > Content Types.
There's a lovely default that already exists for field templates. Here it is:
<?php foreach ($items as $delta => $item) : ?> <?php print render($item); ?> <?php endforeach; ?>
That's great, but the problem here is the render() function. That's exactly what we don't want: pre-processed output from the field. We want to reach inside the field, pull out the raw data inside, and serve it up with seaweed and rice. Here's how:
$nid = arg(1); // Grab the node id from the url $node = node_load($nid); // Load the node you want $geo = field_get_items('node', $node, 'your_field_here'); // Load the field from the node
The field will be loaded as an array with all its bits and pieces inside. You can use a print_r() to figure out what's in there and how to grab it. Here's what it really looks like:
$nid = arg(1); // Grab the node id from the url $node = node_load($nid); // Load the node you want $geo = field_get_items('node', $node, 'field_location_computed'); // Load the field from the node $lat = $geo[0]['lat']; $lon = $geo[0]['lon']; print '<div class="static"><img src="http://ojw.dev.openstreetmap.org/StaticMap/?show=1&layer=mapnik&z=17&size=500x500&mlat0=' . $lat . '&mlon0=' . $lon . '&lat=' . $lat . '&lon=' . $lon . '" /></div>';