{"id":5652,"date":"2026-02-12T20:45:01","date_gmt":"2026-02-13T01:45:01","guid":{"rendered":"https:\/\/chubes.net\/?documentation=hooks"},"modified":"2026-03-13T03:28:31","modified_gmt":"2026-03-13T07:28:31","slug":"hooks","status":"publish","type":"documentation","link":"https:\/\/chubes.net\/docs\/wordpress-core\/html-api\/hooks\/","title":{"rendered":"Hooks"},"content":{"rendered":"<p>The HTML API does not define any actions or filters. (Verified: no <code>do_action<\/code> or <code>apply_filters<\/code> calls exist in any source file under <code>wp-includes\/html-api\/<\/code>.)<\/p><p><strong>Source:<\/strong> <code>wp-includes\/html-api\/<\/code><\/p><hr class=\"wp-block-separator\"\/><h2 class=\"wp-block-heading\">Overview<\/h2><p>The HTML API is designed as a pure parsing and modification library without WordPress hook integration. It operates on HTML strings directly without triggering actions or applying filters.<\/p><p>This design choice keeps the API:<\/p><ul class=\"wp-block-list\"><li><strong>Fast<\/strong> \u2014 No hook overhead during parsing<\/li><li><strong>Predictable<\/strong> \u2014 Output depends only on input and method calls<\/li><li><strong>Isolated<\/strong> \u2014 No side effects from other plugins<\/li><li><strong>Testable<\/strong> \u2014 Easy to unit test without WordPress context<\/li><\/ul><hr class=\"wp-block-separator\"\/><h2 class=\"wp-block-heading\">Integration Points<\/h2><p>If you need hook-like behavior, implement it at the calling layer:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">\/\/ Apply filters before processing\n$html = apply_filters( &#039;my_plugin_before_html_processing&#039;, $html );\n\n$processor = new WP_HTML_Tag_Processor( $html );\nwhile ( $processor-&gt;next_tag( &#039;img&#039; ) ) {\n    $processor-&gt;set_attribute( &#039;loading&#039;, &#039;lazy&#039; );\n}\n$result = $processor-&gt;get_updated_html();\n\n\/\/ Apply filters after processing\n$result = apply_filters( &#039;my_plugin_after_html_processing&#039;, $result );<\/code><\/pre><\/div><hr class=\"wp-block-separator\"\/><h2 class=\"wp-block-heading\">Related WordPress Hooks<\/h2><p>While the HTML API itself has no hooks, it&#8217;s often used in contexts where WordPress hooks apply:<\/p><h3 class=\"wp-block-heading\">Content Filters<\/h3><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">add_filter( &#039;the_content&#039;, function( $content ) {\n    $processor = new WP_HTML_Tag_Processor( $content );\n    while ( $processor-&gt;next_tag( &#039;a&#039; ) ) {\n        $href = $processor-&gt;get_attribute( &#039;href&#039; );\n        if ( $href &amp;&amp; str_starts_with( $href, &#039;http&#039; ) ) {\n            $processor-&gt;set_attribute( &#039;rel&#039;, &#039;noopener&#039; );\n        }\n    }\n    return $processor-&gt;get_updated_html();\n} );<\/code><\/pre><\/div><h3 class=\"wp-block-heading\">Block Rendering<\/h3><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">add_filter( &#039;render_block&#039;, function( $block_content, $block ) {\n    if ( &#039;core\/image&#039; !== $block[&#039;blockName&#039;] ) {\n        return $block_content;\n    }\n    \n    $processor = new WP_HTML_Tag_Processor( $block_content );\n    if ( $processor-&gt;next_tag( &#039;img&#039; ) ) {\n        $processor-&gt;add_class( &#039;block-image&#039; );\n    }\n    return $processor-&gt;get_updated_html();\n}, 10, 2 );<\/code><\/pre><\/div><h3 class=\"wp-block-heading\">Widget Output<\/h3><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">add_filter( &#039;widget_text_content&#039;, function( $content ) {\n    $processor = WP_HTML_Processor::create_fragment( $content );\n    \/\/ Structure-aware modifications...\n    return $processor-&gt;get_updated_html() ?? $content;\n} );<\/code><\/pre><\/div>","protected":false},"excerpt":{"rendered":"<p>The HTML API does not define any actions or filters. (Verified: no do_action or apply_filters calls exist in any source file under wp-includes\/html-api\/.) Source: wp-includes\/html-api\/ Overview The HTML API is&#8230;<\/p>\n","protected":false},"featured_media":0,"template":"","meta":{"footnotes":""},"tags":[],"project":[629],"project_type":[749],"class_list":["post-5652","documentation","type-documentation","status-publish","hentry","project-html-api","project_type-wordpress-reference"],"project_info":{"id":589,"name":"WordPress Core","slug":"wordpress-core"},"project_type_info":{"id":749,"name":"WordPress Reference","slug":"wordpress-reference"},"_links":{"self":[{"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/documentation\/5652","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/documentation"}],"about":[{"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/types\/documentation"}],"version-history":[{"count":4,"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/documentation\/5652\/revisions"}],"predecessor-version":[{"id":8876,"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/documentation\/5652\/revisions\/8876"}],"wp:attachment":[{"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/media?parent=5652"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/tags?post=5652"},{"taxonomy":"project","embeddable":true,"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/project?post=5652"},{"taxonomy":"project_type","embeddable":true,"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/project_type?post=5652"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}