Hooks and filters in the Dirigible theme
Hooks are spots in the theme where your own code can run. There are two kinds:
- Actions let you add something at that spot, such as a banner under the header or a note after every blog post.
- Filters hand your code a value, such as a link or a block of settings, so you can change it before the theme uses it. A filter must always return the value.
This page lists the WordPress hooks and filters Dirigible Studio provides for customization. Standard WordPress and WooCommerce hooks work too but aren't covered here.
Before you start
- Where the code goes: your child theme's
functions.php, or a code snippets plugin such as Code Snippets. Never edit the parent Dirigible Studio theme. Theme updates replace its files and your changes are lost. - Test on a staging copy first. A typo in PHP can stop the site loading. Make sure you can reach your files through your host or SFTP so you can undo a bad change.
- Escape what you print. Wrap text in
esc_html()and links inesc_url(), as the examples below do.
Each hook below lists its arguments in the order your function receives them.
Add content to pages and posts
All of these are actions. None pass arguments except ds_post_meta.
| Hook | Where it runs |
|---|---|
dirigible_after_masthead |
Right after the site header, on every page |
dirigible_before_page_content,dirigible_after_page_content |
Before and after the content of regular pages and Landing template pages |
dirigible_before_post_content,dirigible_after_post_content |
Before and after the content of blog posts and other single items that use the theme's standard layout |
dirigible_before_post_footer,dirigible_after_post_footer |
Around the end of a blog post, where post details, share links, and older/newer post links appear |
dirigible_before_archive_header,dirigible_after_archive_header |
Around the title area at the top of the blog and category pages |
dirigible_before_archive,dirigible_after_archive |
Before and after the post list (and sidebar) on the blog page |
dirigible_before_archive_posts,dirigible_after_archive_posts |
Right before and after the grid of posts |
ds_post_meta |
At the end of a post's details (date, categories, tags). Receives $context: 'postmeta' for the main details block, 'sidebar' for the details in the post sidebar layout |
Add a newsletter prompt after every blog post. Blog comments are added at the default priority (10), so priority 5 puts your prompt above them:
add_action('dirigible_after_post_content', function () {
if (!is_singular('post')) {
return;
}
echo '<p class="mt-8"><strong>Enjoyed this post?</strong> <a href="' . esc_url('/newsletter/') . '">Join our newsletter</a>.</p>';
}, 5);
Add a reading-time line to post details:
add_action('ds_post_meta', function ($context) {
if ($context !== 'postmeta') {
return;
}
$words = str_word_count(wp_strip_all_tags(get_the_content()));
$minutes = max(1, (int) round($words / 200));
echo '<p class="mb-0">' . esc_html($minutes . ' min read') . '</p>';
});
Header, menu, and pop-up
All actions, no arguments.
| Hook | Where it runs |
|---|---|
ds_navigation_begin,ds_navigation_end |
At the start and end of the main header bar. Available on most header layouts but not Centered |
ds_nav_links |
After the menu, search, login, and cart icons, before the header button. Also runs in the mobile menu |
ds_after_logo_image |
Right after the logo. Anything you add here is inside the logo's home-page link |
ds_utility_nav_end |
At the end of the utility bar above the header, when the utility bar is on |
dirigible_popup_upper,dirigible_popup_lower |
At the top of the site pop-up (above the headline) and at the bottom (after the form, before the button) |
Add a phone link next to the menu, using the Phone number from Footer & Contact β Contact Information. ds_get_setting() reads any Dirigible Customizer value:
add_action('ds_nav_links', function () {
$phone = ds_get_setting('ds_footer_phone');
if (!$phone) {
return;
}
$tel = preg_replace('/[^0-9+]/', '', $phone);
echo '<a href="' . esc_url('tel:' . $tel) . '">' . esc_html($phone) . '</a>';
});
Because ds_nav_links also runs in the mobile menu, the link shows in both places.
Footer
| Hook | Where it runs |
|---|---|
ds-footer |
The theme prints its footer here at priority 10. Use a lower number to add content above it, higher to add content below |
ds-attribution |
The credit line at the very bottom of the page. To hide it, turn off Dirigible Attribution in Appearance β Customize β Settings β General instead of writing code |
add_action('ds-footer', function () {
echo '<p class="py-4 text-center">' . esc_html('Proudly serving Dane County since 1998.') . '</p>';
}, 5);
Blog post links (filters)
| Filter | Changes | Arguments |
|---|---|---|
ds_post_return_link |
The Return to Blog link on single posts | $html, $post_id |
ds_prev_post_link |
The Older Post link | $html, $prev_post, $post_id |
ds_next_post_link |
The Newer Post link | $html, $next_post, $post_id |
$prev_post and $next_post are the neighboring posts. The older and newer filters also run for the smaller links in the post sidebar layout. Return an empty string to hide a link.
add_filter('ds_prev_post_link', function ($html) {
return str_replace('Older Post', 'Previous article', $html);
});
add_filter('ds_next_post_link', function ($html) {
return str_replace('Newer Post', 'Next article', $html);
});
Structured data (filters)
Dirigible adds structured data (JSON-LD) that tells search engines about your business and content. See Structured Data for Search Engines.
| Filter | Changes | Arguments |
|---|---|---|
ds_jsonld_global_schema |
The sitewide business details: name, address, contact, logo, social profiles | $schema |
ds_jsonld_post_type_schema |
The details for a single item, such as a blog post | $schema, $post_type |
ds_jsonld_{post_type}_schema |
Same, for one post type only (for example ds_jsonld_post_schema) |
$schema |
ds_jsonld_schemas |
The full list of items on the page, just before output | $schemas |
ds_jsonld_output |
The final output. Return an empty value to print nothing | $output |
Dirigible saves the results to keep pages fast. Changes from ds_jsonld_global_schema appear after you next click Publish in the Customizer. Changes to a single item appear after you next update that post. ds_jsonld_schemas and ds_jsonld_output run on every page load.
Mark the business as a more specific type:
add_filter('ds_jsonld_global_schema', function ($schema) {
$schema['@type'] = 'Dentist';
$schema['priceRange'] = '$$';
return $schema;
});
SVG uploads and inline SVG (filters)
| Filter | Changes | Default |
|---|---|---|
ds_svg_upload_capability |
The user capability needed to upload SVG files | 'manage_options' (administrators) |
ds_svg_user_can_upload |
The final yes or no for the current user | Result of the capability check |
ds_svg_allowed_tags,ds_svg_allowed_attributes |
The SVG elements and attributes kept when an upload is cleaned | The built-in safe list |
ds_svg_inline_class |
The class that marks images to swap for inline SVG | 'style-svg' |
ds_svg_force_inline |
Inline every SVG image, with or without the class | false |
ds_svg_skip_nested |
When the class is on a container, inline only images directly inside it | false |
The three inline filters only matter when Inline SVG is on in Appearance β Customize β Settings β General.
Let editors upload SVGs:
add_filter('ds_svg_upload_capability', function () {
return 'edit_pages';
});
Only widen the allowed tags and attributes if you know the SVGs come from a trusted source. The cleanup is there to block harmful code hidden in image files.
Media uploads (filters)
Dirigible stops anyone uploading an exact copy of a file that's already in the Media Library. Both filters receive $value (default false) and $file, the upload being checked. Return true to let the upload through.
| Filter | Use it to |
|---|---|
dirigible_skip_duplicate_upload_check |
Skip the duplicate check entirely |
dirigible_allow_duplicate_upload |
Allow the duplicate after the check |
Let administrators upload duplicates:
add_filter('dirigible_allow_duplicate_upload', function ($allow) {
return current_user_can('manage_options') ? true : $allow;
});
Dashboard and admin (filters)
Useful for agencies that want to brand the WordPress Dashboard for a client.
| Filter | Changes | Value |
|---|---|---|
ds_dashboard_welcome_description |
The paragraph under the Dashboard greeting | A string |
ds_dashboard_welcome_intro |
The first welcome panel | ['title' => β¦, 'html' => β¦] |
ds_dashboard_welcome_icon |
The image beside the greeting (your site icon by default) | ['url' => β¦, 'alt' => β¦] |
ds_dashboard_welcome_sections |
The list of Dashboard panels and their jump links | An array of panels, each with id, label, and callback |
ds_documentation_url |
The page shown at Dashboard β Documentation | A URL |
add_filter('ds_dashboard_welcome_description', function () {
return 'Need help? Email support@example.com and we will get back to you within a day.';
});
Add a Dashboard panel. The callback prints the panel and receives the panel's settings:
add_filter('ds_dashboard_welcome_sections', function ($sections) {
$sections[] = [
'id' => 'ds-welcome-agency',
'label' => 'Support',
'callback' => function ($section) {
echo '<div id="' . esc_attr($section['id']) . '" class="ds-docs-group ds-docs-panel">';
echo '<h2>Support</h2><p>Call us at (555) 555-0123.</p>';
echo '</div>';
},
];
return $sections;
});
For plugin developers (filters)
These are how Dirigible's own plugins plug into the theme.
| Filter | Lets you | Arguments |
|---|---|---|
ds_admin_toasts |
Show a small status message (a toast) on wp-admin screens | $toasts, $context |
ds_sample_data_sources |
Add an entry to Import sample data on Dirigible β Import/Export | $sources |
Each toast in $toasts is an array with id, token, type (working, success, error, or info), and message. Optional keys are detail, dismissible, dismiss_on_navigate, and poll_interval (milliseconds, for working toasts that should keep checking back). Toasts missing an id, token, or message are dropped.
add_filter('ds_admin_toasts', function ($toasts, $context) {
if (get_transient('my_plugin_import_running')) {
$toasts[] = [
'id' => 'my-plugin/import',
'token' => 'import-1',
'type' => 'working',
'message' => 'Importing productsβ¦',
'poll_interval' => 3000,
];
}
return $toasts;
}, 10, 2);
Each sample data source is an array with id, title, an optional description, and wxr: the full path to a WordPress export file. Add requires with plugin file names (such as 'my-plugin/my-plugin.php') to show the entry only when those plugins are active.
Tools & Maintenance limits (filters)
| Filter | Changes | Default |
|---|---|---|
ds_maintenance_audit_links_max_per_post |
How many links Audit broken links checks per post | 30 |
ds_maintenance_link_check_cache_ttl |
How long, in seconds, a link check result is remembered | 300 |
ds_maintenance_attachment_alt_meta_key |
Where Sync alt tags reads each image's alt text from. Receives $key and $attachment_id |
WordPress's standard alt text |
See Using Tools & Maintenance for what each tool does.