Docs

Hooks & Filters

5 min readUpdated September 19, 2026

Every place this plugin generates something (a rendered block, a shortcode, an OpenAPI-to-block conversion) exposes plain WordPress actions and filters around it, so you can adjust the output without editing plugin files or forking anything. This doc is a reference for those hooks: what each one receives, what it expects back, and when it fires. It’s aimed at developers extending the plugin from a theme’s functions.php or their own plugin, not at day-to-day content authors.

Color and dark-mode theming has its own dedicated set of filters and a small JS API. Those are covered in the next doc, Theming & dark mode, rather than here.

Rendering filters#

nahnu_code_block_wrapper_classes#

Add your own CSS classes to the code block’s outer wrapper. Applies to the plain code block only, not the eleven API-documentation blocks.

Add a wrapper class
add_filter( 'nahnu_code_block_wrapper_classes', function ( $classes, $attributes ) {
    $classes[] = 'my-theme-code-block';
    return $classes;
}, 10, 2 );

nahnu_code_block_pre_attributes#

Add extra HTML attributes to every <pre> element the plugin renders (the code block’s inline preview and modal, plus the Request/Response and Status Codes blocks). Return an associative array of attribute name to value. This exists mainly for third-party compatibility: some themes and plugins scan the page for <pre><code> and inject their own copy button or language label into anything they find. If that script respects a marker attribute to skip elements it shouldn’t touch, add the marker here instead of fighting the visual collision with CSS afterward. includes/compat/class-nahnu-code-block-compat-wp-super-docs.php uses this exact filter to keep WP Super Docs’ own injected UI off this plugin’s <pre> elements.

Add a pre attribute
add_filter( 'nahnu_code_block_pre_attributes', function ( $attrs ) {
    $attrs['data-some-plugin-skip'] = '1';
    return $attrs;
} );

nahnu_code_block_collapsed_lines#

Change the default number of lines a code block shows before it collapses behind “View all code.” This is the site-wide default; an individual block’s own “Preview height” setting, when set, still wins over it.

nahnu_code_block_late_style_handles#

A block can end up rendering after wp_head() has already run (for example, one built by nahnu_code_block_render() from inside a shortcode or a late-loading template part). When that happens, the plugin force-prints its own stylesheets so the block still looks right. This filter lets you add your own stylesheet handle to that force-print list, for when you’ve registered additional CSS from one of the nahnu_code_block_openapi_*_attributes filters below and need it guaranteed to load too. Defaults to nahnu-code-block-style, nahnu-code-block-api-style, and nahnu-code-block-prism-line-numbers.

Rendering action#

nahnu_code_block_assets_enqueued#

Fires once per request, the moment the plugin confirms one of its blocks is actually present on the page and has enqueued its own assets. Use this instead of an unconditional wp_enqueue_scripts hook if your own inline CSS or JS should only load on pages that actually use Nahnu Code Block.

Enqueue conditional assets
add_action( 'nahnu_code_block_assets_enqueued', function () {
    wp_add_inline_style( 'nahnu-code-block-style', '/* your CSS */' );
} );

Shortcode#

The shortcode itself doesn’t add any hooks of its own beyond the rendering filters above, which apply to it the same as any other way of placing a block on the page. It ultimately calls the same rendering path as nahnu_code_block_render(), so a nahnu_code_block_pre_attributes or nahnu_code_block_wrapper_classes filter you’ve added fires for shortcode-placed blocks too, with no extra setup.

If you’re customizing per-instance branding colors, note that the shortcode accepts its own plain attributes for that (accentColor, bgColor, and so on) rather than requiring a filter. See the Theming & dark mode doc for the full list.

OpenAPI conversion filters#

The Nahnu_Code_Block_Openapi class (see the developer doc on building your own importer) filters every set of block attributes it builds from a resolved operation, right before handing them back. Each filter receives the attributes array plus the OpenAPI data that produced it, so you can adjust or add fields the built-in mapping doesn’t cover, without forking the converter.

FilterFires forExtra arguments
nahnu_code_block_openapi_endpoint_attributesEndpoint block$operation
nahnu_code_block_openapi_parameters_attributesParameters block, from an operation’s own inline parameters$operation
nahnu_code_block_openapi_schema_definition_attributesParameters block, from a named reusable schema definition$name, $schema
nahnu_code_block_openapi_response_body_attributesResponse Body block$operation
nahnu_code_block_openapi_status_codes_attributesStatus Codes block$operation
nahnu_code_block_openapi_auth_attributesAuth block$requirement, $security_schemes
nahnu_code_block_openapi_servers_attributesServers block$servers
Customize OpenAPI endpoint mapping
add_filter( 'nahnu_code_block_openapi_endpoint_attributes', function ( $attrs, $operation ) {
    if ( ! empty( $operation['x-internal'] ) ) {
        $attrs['version'] = 'internal';
    }
    return $attrs;
}, 10, 2 );

Two more filters sit above the individual blocks:

  • nahnu_code_block_openapi_operation_blocks filters the complete set of block markup (keyed by block slug) built for one operation, after every individual block above has already run. Use this if you want to drop a block the built-in mapping would otherwise include, or splice in markup for a block type the converter doesn’t generate.
  • nahnu_code_block_openapi_callback_blocks filters the block markup built for an OpenAPI callbacks object (an operation that itself triggers a webhook-style callback), receiving the callback’s name, its runtime expression URL, and the parent operation.

Other integration points#

These aren’t hooks, but come up in the same kind of work:

Deep-link anchor IDs. Parameters and Endpoint blocks each get a page-unique, stable HTML id (derived from the parameter name, or the endpoint’s method and path) with a small link icon that copies a direct URL to that item. If you’re writing a custom block that should participate in the same page-wide uniqueness tracking, so your own ids never collide with this plugin’s, call:

Get a unique anchor id
$id = Nahnu_Code_Block::instance()->nahnu_code_block_unique_anchor_id( 'some raw text' );
// => "nahnu-code-block-anchor-some-raw-text", or "...-2" etc. on collision

Enqueued handles. If you just need correct load order (your own CSS loading after this plugin’s, say), these are the stable, public handle names: nahnu-code-block-style (base styles plus generated theme CSS), nahnu-code-block-frontend (copy/expand/theme-toggle behavior and the window.NahnuCodeBlock API), nahnu-code-block-api-style and nahnu-code-block-api-frontend (the API-documentation blocks’ shared styles and behavior), and nahnu-code-block-prism-core plus nahnu-code-block-prism-lang-{language} (only enqueued on pages with highlighted code, one per language actually used).

Color and dark-mode filters (nahnu_code_block_theme_variables, nahnu_code_block_dark_mode_selectors, nahnu_code_block_light_mode_selectors) and the JavaScript theming API live in the next doc.

Tips#

  • Always return the value in a filter callback, not just the parts you changed. A callback that reads $attrs['version'] and forgets to return $attrs will blank out everything else in the array for the rest of the pipeline.
  • Prefer the narrowest filter that gets the job done. If you only need to change how one block’s OpenAPI mapping works, use that block’s own nahnu_code_block_openapi_*_attributes filter rather than the broader nahnu_code_block_openapi_operation_blocks, so you’re not re-implementing logic the plugin already handles correctly.
  • Hook priority matters when more than one thing filters the same value. The built-in Settings page saves its own colors at priority 5, specifically so a developer’s own nahnu_code_block_theme_variables filter (the normal default priority, 10) can still override it. Keep that in mind if you’re layering your own filters on top of a client’s settings-page configuration.
  • Test a filter against a real render, not just against the array shape. Some attributes (colors, in particular) are validated and silently dropped if they don’t look like a real value, so a filter that returns something slightly malformed won’t error, it’ll just have no visible effect.

This website uses cookies to enhance your browsing experience and ensure the site functions properly. By continuing to use this site, you acknowledge and accept our use of cookies.

Accept All Accept Required Only