Single Doc Template
Last Updated: April 20, 2026
single-doc.php
This will serve as the controller for the CPT single page template.
<?php
/**
* Template for displaying a single doc post
*/
$context = Timber::context(); // Get the Timber context
// Get the current post
$post = new Timber\Post();
$context['post'] = $post;
// ACF fields
$context['code_window'] = get_field('code_window'); // Code window (WYSIWYG)
$context['important_noteswarnings'] = get_field('important_noteswarnings'); // Important notes and warnings (WYSIWYG)
$context['linkreference1'] = get_field('linkreference1');
$context['link_title_1'] = get_field('link_title_1');
$context['link_title_2'] = get_field('link_title_2');
$context['link_title_3'] = get_field('link_title_3');
$context['linkreference2'] = get_field('linkreference2');
$context['linkreference3'] = get_field('linkreference3');
$context['last_updated_date'] = get_field('last_updated_date'); // Last updated date
$context['imagescreenshot1'] = get_field('imagescreenshot1');
$context['image2'] = get_field('imagescreenshot2');
$context['image3'] = get_field('imagescreenshot3');
$context['related_documentation'] = get_field('related_documentation'); // Related docs (Relationship)
// Prepare an array to store related posts' details
$related_docs = [];
if ($related_documentation) {
foreach ($related_documentation as $related_doc) {
$related_docs[] = [
'title' => get_the_title($related_doc->ID),
'permalink' => get_permalink($related_doc->ID),
'excerpt' => get_the_excerpt($related_doc->ID)
];
}
}
$context['related_docs'] = $related_docs;
// Custom Taxonomies
$context['frameworks'] = Timber::get_terms([
'taxonomy' => 'framework',
'object_ids' => $post->ID, // Fetch only terms for this post
]);
$context['languages'] = Timber::get_terms([
'taxonomy' => 'language',
'object_ids' => $post->ID, // Fetch only terms for this post
]);
$context['cmss'] = Timber::get_terms([
'taxonomy' => 'cms',
'object_ids' => $post->ID, // Fetch only terms for this post
]);
$context['configs'] = Timber::get_terms([
'taxonomy' => 'config',
'object_ids' => $post->ID, // Fetch only terms for this post
]);
// Render the Twig template
Timber::render('single-doc.twig', $context);
Code Snippet
single-doc.twig
This will be the Twig template to display the content of the “doc” custom post type.
{% extends '_layout/base.twig' %}
{% block content %}
<div class="container flex flex-col my-8 lg:flex-row lg:my-16 lg:space-x-12">
<aside class="bg-gray-100 lg:w-1/3 p-6">
{% if cmss %}
<div class="mb-8">
<div class="flex flex-wrap">
{% for cms in cmss %}
<div
class="relative mb-4 mr-4 w-12 h-12 bg-white">
{# Display the icon image #}
{% if cms.icon_image %}
<img src="{{ cms.icon_image.sizes.thumbnail }}" alt="{{ cms.name }} icon" class="w-full h-full object-contain">
{% endif %}
{# Title that appears on hover #}
<span class="absolute inset-0 flex items-center justify-center bg-black bg-opacity-75 text-white text-sm font-semibold opacity-0 hover:opacity-100 transition-opacity">
{{ cms.name }}
</span>
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% if frameworks %}
<div class="mb-8">
<div class="flex flex-wrap">
{% for framework in frameworks %}
<div
class="relative mb-4 mr-4 w-12 h-12 bg-white">
{# Display the icon image #}
{% if framework.icon_image %}
<img src="{{ framework.icon_image.sizes.thumbnail }}" alt="{{ framework.name }} icon" class="w-full h-full object-contain">
{% endif %}
{# Title that appears on hover #}
<span class="absolute inset-0 flex items-center justify-center bg-black bg-opacity-75 text-white text-sm font-semibold opacity-0 hover:opacity-100 transition-opacity">
{{ framework.name }}
</span>
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% if languages %}
<div class="mb-8">
<div class="flex flex-wrap">
{% for language in languages %}
<div
class="relative mb-4 mr-4 w-12 h-12 bg-white">
{# Display the icon image #}
{% if language.icon_image %}
<img src="{{ language.icon_image.sizes.thumbnail }}" alt="{{ language.name }} icon" class="w-full h-full object-contain">
{% endif %}
{# Title that appears on hover #}
<span class="absolute inset-0 flex items-center justify-center bg-black bg-opacity-75 text-white text-sm font-semibold opacity-0 hover:opacity-100 transition-opacity">
{{ language.name }}
</span>
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% if configs %}
<div class="mb-8">
<div class="flex flex-wrap">
{% for config in configs %}
<div
class="relative mb-4 mr-4 w-12 h-12 bg-white">
{# Display the icon image #}
{% if config.icon_image %}
<img src="{{ config.icon_image.sizes.thumbnail }}" alt="{{ config.name }} icon" class="w-full h-full object-contain">
{% endif %}
{# Title that appears on hover #}
<span class="absolute inset-0 flex items-center justify-center bg-black bg-opacity-75 text-white text-sm font-semibold opacity-0 hover:opacity-100 transition-opacity">
{{ config.name }}
</span>
</div>
{% endfor %}
</div>
</div>
{% endif %}
<section class="my-6 p-4 bg-white">
<h2 class="text-xl font-semibold">Related Links</h2>
<ul>
{% if linkreference1 %}
<li>
<a href="{{ linkreference1 }}">{{ link_title_1 }}</a>
</li>
{% endif %}
{% if linkreference2 %}
<li>
<a href="{{ linkreference2 }}">{{ linkreference2 }}</a>
</li>
{% endif %}
{% if linkreference3 %}
<li>
<a href="{{ linkreference3 }}">{{ linkreference3 }}</a>
</li>
{% endif %}
</ul>
</section>
{% if related_documentation %}
<section class="my-6 p-4 bg-white">
<h2 class="text-xl font-semibold">Related Docs/snippets</h2>
<ul>
{% for related_doc in related_documentation %}
<li>
<a href="{{ related_doc.post_name}}">{{ related_doc.post_title }}</a>
</li>
{% endfor %}
</ul>
</section>
{% endif %}
</aside>
<main class="lg:w-2/3">
<article class="copy">
<h1>{{ post.title }}</h1>
{% if last_updated_date %}
<p class="text-sm text-gray-500">Last Updated:
{{ last_updated_date|date("F j, Y") }}</p>
{% endif %}
{{post.content}}
{# Last updated date #}
{# Code Window (WYSIWYG) #}
{% if code_window %}
<section class="my-6 ">
<h2 class="text-xl font-semibold">Code Snippet</h2>
<div>{{ code_window|raw }}</div>
</section>
{% endif %}
{# Important Notes and Warnings (WYSIWYG) #}
{% if important_noteswarnings %}
<section class="my-6 p-4 bg-red-100">
<h2 class="text-xl font-semibold">Important Notes/Warnings</h2>
<div class="prose">{{ important_noteswarnings }}</div>
</section>
{% endif %}
<section class="my-6 p-4">
<div
class="max-w-7xl mx-auto p-5">
{# {% set screenshot = post.meta('screenshot') %} #}
{% if imagescreenshot1 %}
<div class="grid grid-cols-2 md:grid-cols-3 gap-4">
<img src="{{ imagescreenshot1.url }}">
</div>
{% endif %}
{% if image2 %}
<div class="grid grid-cols-2 md:grid-cols-3 gap-4">
<img src="{{ image2}}">
</div>
{% endif %}
{% if image3 %}
<div class="grid grid-cols-2 md:grid-cols-3 gap-4">
<img src="{{ image3 }}">
</div>
{% endif %}
</div>
</section>
{# Links (Image and URL fields) #}
</article>
</main>
</div>
{% endblock %}