@prefix sioc: <http://rdfs.org/sioc/ns#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix content: <http://purl.org/rss/1.0/modules/content/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

<https://lhero.org/?post_type=lh-portfolio-doc&#038;p=150136>
  a sioc:Post ;
  dc:title "Templates and blocks" ;
  dcterms:identifier 150136 ;
  dc:modified "2026-10-13T12:04:40Z"^^xsd:dateTime ;
  dc:created "2026-10-13T11:40:19Z"^^xsd:dateTime ;
  sioc:link <https://lhero.org/portfolio/lh-baskerville/templates-and-blocks/> ;
  sioc:has_creator <https://lhero.org/author/1/#account> ;
  sioc:has_container <https://lhero.org/#posts> ;
  content:encoded """<ul class="lh_portfolio-meta"><li><strong>Part of:</strong> <a href="https://lhero.org/portfolio/lh-baskerville/">LH Baskerville</a></li></ul>
<h2 class="wp-block-heading">Hybrid classic and block templates</h2>



<p class="wp-block-paragraph"><code>functions.php</code> adds theme support for <code>block-templates</code> and <code>block-template-parts</code>. A post type with a block template in <code>/templates</code> (for example <code>single-lh-portfolio.html</code>) uses it; everything else keeps the classic PHP templates inherited from Baskerville or overridden here.</p>



<h2 class="wp-block-heading">Shared markup functions</h2>



<p class="wp-block-paragraph">The header, footer and post furniture live in pluggable functions that both the classic templates and the block templates call, so there is one source and nothing to keep in sync by hand:</p>



<ul class="wp-block-list">
<li><code>lh_baskerville_header_markup()</code> and <code>lh_baskerville_footer_markup()</code> in <code>includes/template-parts.php</code>: the header image, logo or site title, primary and mobile menus, search toggle, footer widget areas (with fallbacks) and credits.</li>



<li><code>lh_baskerville_post_meta_markup()</code>, <code>lh_baskerville_sidebar_markup()</code> and <code>lh_baskerville_comments_markup()</code> in <code>includes/legacy-post-content.php</code>: the author box, date, categories and tags, previous/next links, sidebar and comments.</li>



<li><code>lh_baskerville_breadcrumbs_markup()</code> in <code>includes/legacy-breadcrumbs.php</code>: renders core&#8217;s <code>core/breadcrumbs</code> block with a manually built postId/postType context on singular pages. Called once, at the end of the header markup.</li>
</ul>



<h2 class="wp-block-heading">Dynamic blocks</h2>



<p class="wp-block-paragraph">Registered on <code>init</code>, each a thin wrapper that captures one of the functions above:</p>



<ul class="wp-block-list">
<li><code>lh/legacy-header</code>, <code>lh/legacy-footer</code>, <code>lh/legacy-post-meta</code>, <code>lh/legacy-sidebar</code>, <code>lh/legacy-comments</code> (<code>includes/legacy-chrome-blocks.php</code>)</li>



<li><code>lh/portfolio-toc</code> (<code>includes/portfolio-toc-block.php</code>): lists an LH Portfolio root&#8217;s child entries by <code>menu_order</code> then title. Visitors see published children only; users who can <code>edit_posts</code> also see draft and private ones, marked with their status.</li>
</ul>



<h2 class="wp-block-heading">Block Bindings</h2>



<p class="wp-block-paragraph"><code>includes/block-bindings.php</code> registers two sources, each inactive unless its plugin is loaded:</p>



<ul class="wp-block-list">
<li><code>lh/kb-entry</code> (LH Knowledge Base): fields <code>entry_type</code>, <code>last_updated</code>, <code>md_url</code>.</li>



<li><code>lh/portfolio</code> (LH Portfolio): fields <code>type</code>, <code>lifecycle_stage</code>, <code>parent_title</code>, <code>parent_url</code>.</li>
</ul>



<p class="wp-block-paragraph">A <code>render_block</code> filter removes any bound block with the class <code>lh-hide-if-empty</code> when its bound text resolves empty or its bound <code>href</code>/<code>src</code> is blank.</p>



<h2 class="wp-block-heading">Skip links</h2>



<p class="wp-block-paragraph">The header markup outputs the theme&#8217;s own skip link to <code>#site-content</code> on every page. Core&#8217;s auto-injected block-template skip link is removed (its <code>wp_enqueue_scripts</code> hook is unhooked and the <code>wp-block-template-skip-link</code> handles are dequeued at priority 100) so block-template pages do not show two. Any future block template that does not use <code>lh/legacy-header</code> would need its own skip link.</p>



<h2 class="wp-block-heading">WooCommerce</h2>



<p class="wp-block-paragraph">The theme declares WooCommerce support but ships no WooCommerce templates (they were removed in 0.2.2), so shop pages use WooCommerce&#8217;s own templates inside the theme&#8217;s header and footer.</p>
"""^^rdf:XMLLiteral ;
  sioc:content """Part of: LH Baskerville
Hybrid classic and block templates



functions.php adds theme support for block-templates and block-template-parts. A post type with a block template in /templates (for example single-lh-portfolio.html) uses it; everything else keeps the classic PHP templates inherited from Baskerville or overridden here.



Shared markup functions



The header, footer and post furniture live in pluggable functions that both the classic templates and the block templates call, so there is one source and nothing to keep in sync by hand:




lh_baskerville_header_markup() and lh_baskerville_footer_markup() in includes/template-parts.php: the header image, logo or site title, primary and mobile menus, search toggle, footer widget areas (with fallbacks) and credits.



lh_baskerville_post_meta_markup(), lh_baskerville_sidebar_markup() and lh_baskerville_comments_markup() in includes/legacy-post-content.php: the author box, date, categories and tags, previous/next links, sidebar and comments.



lh_baskerville_breadcrumbs_markup() in includes/legacy-breadcrumbs.php: renders core&#8217;s core/breadcrumbs block with a manually built postId/postType context on singular pages. Called once, at the end of the header markup.




Dynamic blocks



Registered on init, each a thin wrapper that captures one of the functions above:




lh/legacy-header, lh/legacy-footer, lh/legacy-post-meta, lh/legacy-sidebar, lh/legacy-comments (includes/legacy-chrome-blocks.php)



lh/portfolio-toc (includes/portfolio-toc-block.php): lists an LH Portfolio root&#8217;s child entries by menu_order then title. Visitors see published children only; users who can edit_posts also see draft and private ones, marked with their status.




Block Bindings



includes/block-bindings.php registers two sources, each inactive unless its plugin is loaded:




lh/kb-entry (LH Knowledge Base): fields entry_type, last_updated, md_url.



lh/portfolio (LH Portfolio): fields type, lifecycle_stage, parent_title, parent_url.




A render_block filter removes any bound block with the class lh-hide-if-empty when its bound text resolves empty or its bound href/src is blank.



Skip links



The header markup outputs the theme&#8217;s own skip link to #site-content on every page. Core&#8217;s auto-injected block-template skip link is removed (its wp_enqueue_scripts hook is unhooked and the wp-block-template-skip-link handles are dequeued at priority 100) so block-template pages do not show two. Any future block template that does not use lh/legacy-header would need its own skip link.



WooCommerce



The theme declares WooCommerce support but ships no WooCommerce templates (they were removed in 0.2.2), so shop pages use WooCommerce&#8217;s own templates inside the theme&#8217;s header and footer.
""" ;
  sioc:topic <https://lhero.org/?taxonomy=author&term=cap-1> .

<https://lhero.org/author/1/#account> rdfs:seeAlso <https://lhero.org/author/1/?feed=lhrdf&format=turtle> .
<https://lhero.org/?taxonomy=author&term=cap-1> rdfs:seeAlso <https://lhero.org/?taxonomy=author&term=cap-1&feed=lhrdf&format=turtle> .
