Where is my content coming from?
James Williams
I was asked at Drupalcamp London how to identify where parts of a panel come from. Whether you need to change something on a site you inherited, are looking to trace your steps back on something you created long ago, or need to understand how to fix a colleague's mistake, it can be helpful to have a toolkit of methods to find out what produces all sorts of mystery content - not just for panels, but also views, blocks, fields, and the like.
Here's what I do when I need to know what produces something on a page:
- Inspect the markup - usually the first step
- Read exports - necessary if your markup does not help
- Use the Theme developer module - especially for designers
- Check configure URLs - useful for blocks
- Find text quickly - with the right tools, this option can be the most universally successful
- Know what to look for
1. Inspect the markup for classes
Either by simply hitting 'view source' or using your browser's inspector tool (e.g. Firebug), if you search for the specific element that you want to identify, there are usually indications on the element of where something came from.
Blocks and views will normally have HTML classes or IDs containing the module and 'delta' (unique block identifier within that module) or display ID (for views). Panel panes will often have helpful classes too, though they don't necessarily correspond exactly to their providing modules. Nodes, taxonomy terms and other entities are often wrapped in markup telling you their type/vocabulary and ID - so finally you can identify which node needs editing on your custom-built page!
Field values & labels are wrapped with classes indicating the type and name of fields, though modules like Fences, Semantic fields and Display Suite, as well as many themes, may remove this extraneous markup.
Here's an example highlighting the identifying classes from our 'Related articles' views block in our sidebar:
Note: Hashed deltas
Block deltas cannot be more than 32 characters long (that's the maximum width of the database column), so some modules trim, or even hash long deltas of blocks & panes - e.g. 'ocUmprGIz8W5LC0N3EM6KpXMwFQJlMIE'. Views' names and display IDs are concatenated together to produce deltas, so they regularly go over that limit. You'll have to use other methods to find out which actual block/pane those are. For example, views uses a variable (i.e. in the 'variable' database table) called 'views_block_hashes' to keep track of its hashes.
2. Reading exports
If you know your content is within a view or panel (or anything similarly exportable), but can't work out which field, pane or other area your content is coming from, it can help to take a look at the exported version of the object. Click the export link (usually towards the top right of administrative interfaces) and take a look. Exports are just PHP code that build up a full representation of the object. They are quite repetitive, so you can usually scan downwards quite quickly to find the part you're looking for, or use your browser's 'find' functionality to jump down a section (e.g. a pane or views field) at a time.
Panel panes have a 'type' and a 'subtype'. Type is usually the module that provides the pane, subtype is the identifier within that module.
In an exported view, each display starts with a call to new_display
, so search for that, and then jump down to the part that you're interested in, for example the lines that start $handler->display->display_options['fields']
for all the fields.
3. Theme developer module
Formerly part of the Devel project, Theme developer module allows you to click on any part of a page, and information will be displayed about how to theme that item. This can give away clues as to where something has come from, as most theme hooks contain module names and useful identifiers.
4. Configure URLs
Finally, when you configure a block, or many other things, part of the URL will tell you information such as which module provides that block, and the block's unique ID/delta. Some administrative interfaces use javascript so you cannot see changes in the URL in the address bar (such as views), but often if you just hover your mouse over links, you'll be able to see the URL in your browser's status bar.
5. Find text quickly
The biggest advance in tracking things down that I have made recently is since I started using the PhpStorm IDE, because it has such a good (i.e. quick) 'find text' function. When simply searching across a whole codebase becomes a quick task, you can get straight to the root of where content comes from in nearly any case.
I know there are other applications that search text quickly too, but I have used many applications that just don't search for simple text strings quickly enough to make this practical. With the right tool, this technique will get you from identifying a problem to starting the solution quicker than anything else and without getting in your way. Spend time solving the problem, not finding the problem!
PhpStorm also allows you to define 'scopes' - so for example, I can limit my searches to contributed modules only, or all custom code, even when spread across different directories in the file tree. See the screenshot to the right for an example use of scopes. At the very least, you should have a way to limit your searches to specific directories (recursively).
But wait, what should I be looking for?
- Any identifiers that you found when inspecting the markup, such as class names or IDs - try swapping hyphens for underscores (perhaps using regular expressions to match either if your text searching functionality supports it)
- Field labels
- Titles and any text you cannot edit (which would be part of Drupal's provided interface)
- Anything that is 'near' the content that you are hunting for if it is potentially part of the same 'thing'.
- Any content that users entered into Drupal's interface will not be found in the codebase though!
Having a good debugging system is an absolute must for any professional developer too. Without it you can only really guess at where things are coming from. Drupal's flexibility means any module can alter nearly anything, so identifying what produces your mystery content can itself be a mystery without the right tools.
What about you?
Are there other techniques that you find helpful for tracking down mystery content? What do you do when you've tried all the above but to no avail? Share your experience in the comments below!