Single Post & Page Templates
How to build custom layouts for individual posts and pages using the Protuno Theme Builder, with full access to post content, metadata, and dynamic fields.
A Single template controls the layout of individual posts, pages, or custom post types. Instead of your theme's default single-post layout, you design exactly what surrounds and follows the content, author box, related posts, sidebar, table of contents, while placing the actual post content using <uichemy-post-content>.
Create A Single Template
- Go to Protuno → Theme Builder
- Click + Add New → Single (Post / Page)
- Elementor opens with the template canvas
- Drag the Proton widget onto the canvas
- Build the layout
- Click Update to save
- Set display conditions
The post Provider In Single Templates
Inside the Proton widget's HTML panel, every post.* Twig expression resolves to the current post being viewed.
post.* fields require Protuno Pro. In Free, only {{ post.title }}, {{ post.content }}, {{ post.link }}, and {{ post.thumbnail }} resolve. Fields like {{ post.date }}, {{ post.author.name }}, {{ post.categories.name }}, {{ post.comment_count }}, and {{ post.meta('key') }} require Pro and return empty in Free builds.<article class="single-post pr-boxed">
<header class="post-header">
<span class="text-label">{{ post.categories.name }}</span>
<h1 class="text-heading-h1">{{ post.title }}</h1>
<p class="post-meta">
By {{ post.author.name }} · {{ post.date|date('F j, Y') }} · {{ post.comment_count }} comments
</p>
{% if post.thumbnail %}
<img
src="{{ post.thumbnail.src('large') }}"
alt="{{ post.thumbnail.alt }}"
class="post-featured-image"
>
{% endif %}
</header>
<div class="post-body">
<uichemy-post-content></uichemy-post-content>
</div>
<footer class="post-footer">
<div class="author-box">
<img src="{{ post.author.avatar('80') }}" alt="{{ post.author.name }}">
<div>
<strong>{{ post.author.name }}</strong>
<p>{{ post.author.bio }}</p>
</div>
</div>
</footer>
</article>
<uichemy-post-content> outputs the full the_content(), whatever the editor saved, including blocks, shortcodes, and embeds.
Table Of Contents
Add <uichemy-toc></uichemy-toc> anywhere in the template to insert a table of contents derived from the post's headings:
<aside class="toc-sidebar">
<h3 class="text-label">Contents</h3>
<uichemy-toc></uichemy-toc>
</aside>
Display Conditions For Singles
| Condition | When to use |
|---|---|
| All Posts | Apply to all blog posts |
| All Pages | Apply to all WordPress pages |
| Single Post → specific post | Override for one particular post |
| Post Type (custom) | Apply to a custom post type |
Example: blog post layout for all posts, but a full-width layout for the homepage:
- Create "Blog Post" template → Include: All Posts
- Create "Homepage" template → Include: Single Page → Home
- The Homepage condition is more specific and wins on that page
Practical: Blog Post With Sidebar
<div class="single-post-layout pr-boxed">
<main class="post-main">
<header>
<h1>{{ post.title }}</h1>
<p class="text-body-sm">{{ post.date|date('F j, Y') }} · {{ post.meta('reading_time') }} min read</p>
</header>
<uichemy-post-content></uichemy-post-content>
</main>
<aside class="post-sidebar">
<div class="widget toc-widget">
<h3 class="text-label">In This Article</h3>
<uichemy-toc></uichemy-toc>
</div>
<div class="widget author-widget">
<img src="{{ post.author.avatar('64') }}" alt="{{ post.author.name }}">
<strong>{{ post.author.name }}</strong>
<a href="{{ post.author.link }}">All posts →</a>
</div>
</aside>
</div>
Frequently Asked Questions
Does the Single template replace the post content or wrap it?
It wraps it. Place <uichemy-post-content> wherever you want the post's own content to appear. Everything else you build in the Proton widget is the surrounding layout.
Can I use a different Single template for different categories? Yes. Create two Single templates and assign conditions:
- Template A: Include → All Posts
- Template B: Include → Post Category → [specific category] (wins due to higher specificity)
Can I show related posts at the bottom?
Yes, use a get_posts loop at the bottom of the template, filtered by the current post's category.