Help & Documentation

1. Pages

Pages are the most crucial elements of your Pubner website. Every URL route corresponds to a specific Page template. When a visitor requests a URL, the system loads the associated Page, processes its Twig code, and injects the output into the defined Layout.

Think of a Page as the "body" of your content. It contains only what is unique to that specific URL (like an article's text, or a specific form), while the global elements (like the navigation bar or footer) are handled by Layouts and Partials.

Render the current page content inside a layout:

{% page %}

2. Partials

Partials are reusable chunks of HTML and Twig logic. By breaking your design into partials, you keep your codebase DRY (Don't Repeat Yourself) and highly organized. If you need to update your site's footer, you only change one partial file, and it instantly updates across the entire site.

Common use cases for partials include headers, footers, sidebar widgets, product cards, or complex UI components that are used on multiple different pages.

Include a partial in your layout or page:

{% partial 'navigation.twig' %}

3. Layouts & Placeholders

Layouts define the core HTML wrapper of your site (the <html>, <head>, and <body> tags). A single project can have multiple layouts (e.g., one for the public site, another for a customer dashboard).

To make layouts flexible, Pubner uses Placeholders. Placeholders act as "hooks" where individual pages can inject custom content, such as specific SEO meta tags, extra CSS stylesheets, or tracking scripts.

Define a placeholder in your layout:

{% placeholder styles %}

Push content to a placeholder from a specific Page:

{% put styles %}
    <style> .custom-hero { background: blue; } </style>
{% endput %}
Content placed between the put tags will be automatically injected exactly where the placeholder is defined in your layout.

4. Variables & Control Logic

Pubner is powered by the modern Twig template engine. This allows you to write clean, secure, and highly dynamic templates without writing pure PHP code.

You can easily output variables, apply filters to transform text, loop through arrays of data (like blog posts or products), and use conditional logic to show or hide elements based on the current state or user session.

Output variables and use conditions:

{% if site().name %}
    <h1>Welcome to {{ site().name }}</h1>
{% endif %}

5. Forms, Assets & UI Helpers

Building interactive elements like contact forms or loading static assets (CSS/JS) is streamlined through our built-in helpers. They automatically handle security (CSRF tokens), routing, and session state.

We also provide an automated paginator generator that will inject a clean, responsive pagination component wherever you need it, creating the necessary partial files on the fly if they don't exist.

Initialize a secure form:

{{ form({'action': 'contact.send', 'redirect': '/thanks'}).open() }}
    {# Form inputs go here #}
{{ form().close() }}

Check for form success/fail alerts:

{% if success() %}
    <div class="alert-success">Message sent successfully!</div>
{% endif %}

Generate Pagination Links:

{{ paginator_links(records) }}
Pass a paginated collection here. Pubner will automatically generate a pagination.twig partial in your theme if it doesn't exist.

6. Routing & Redirects

Navigating users around your application should be safe and predictable. Pubner provides a suite of Twig functions to handle internal and external redirects directly from your templates.

Additionally, you can use the request_is() helper to easily determine the active state of navigation menus, supporting wildcard patterns and localized routes.

Available Redirect Helpers:

{# Redirect to a specific URL #}
{{ redirect('/about') }}

{# Redirect to the previous page #}
{{ redirect_back() }}

{# Redirect only if the user is logged in (Guest protection) #}
{{ redirect_if_auth('/dashboard') }}

{# Safe redirect (Prevents external open-redirect vulnerabilities) #}
{{ redirect_safely(user_provided_url) }}

Check Active Route (Great for Navbars):

{% if request_is('about*', 'contact') %}
    {# This will be true for /about, /about/team, and /contact #}
    <a class="active">Company</a>
{% endif %}

Build Locale-Aware URLs with page_url():

{# Link to a record detail page (locale-aware) #}
<a href="{{ page_url('/news', record.slug) }}">Read more</a>

{# Link to a static page #}
<a href="{{ page_url('/about') }}">About Us</a>

{# Single-language → /news/my-post   Multilingual → /ua/news/my-post #}

7. Localization & Languages

Pubner is built from the ground up for global audiences. The native localization system allows you to translate static text strings and build intelligent language switchers with minimal effort.

The lang() object gives you full control over the URL structure, automatically injecting or updating the language prefix in the current URL while preserving query parameters.

Translate text strings:

{{ t('btn_checkout', 'Proceed to Checkout') }}
Using a default fallback string ensures your layout doesn't break even if the translation key hasn't been saved in the database yet.

Language Switcher Logic:

{# Get current language code (e.g., 'en') #}
{{ lang().current() }}

{# Check if specific language is active #}
{% if lang().is('ua') %}...{% endif %}

{# Generate a URL for a different language (Keeps current path) #}
<a href="{{ lang().url('ua') }}">Українська</a>

8. Global Data Helpers

To build a truly dynamic platform, you need access to the environment. Pubner exposes global helpers to retrieve the current Site's configuration, authenticated user details, and URL payload data.

These helpers fetch data instantly without the need to write complex backend controllers for every single view.

Site Configuration Data:

Site Name: {{ site('name') }}
Primary Email: {{ site().email }}
Available Locales: {{ site().locales | join(', ') }}

Authenticated User &amp; Requests:

{# Get logged-in user name (Returns null if guest) #}
{{ auth('name') }}

{# Get current URL Path parameter #}
{{ path('slug') }}

{# Get $_GET or $_POST request data #}
{{ request('search_query') }}

9. Database Collections (Builders)

The true power of a CMS is querying data. The Builders allow you to query your database records, categories, and areas directly from the template layer. They are extremely fast and automatically respect your site's multi-tenant boundaries.

You can pass filter arrays into these builders to order records, filter by categories, limit results, or paginate them automatically.

Query Records (e.g., Blog Posts or Products):

{% set posts = records({
    'area': 'blog',
    'limit': 10,
    'sort': '-published_at'
}).get() %}
Pass 'area' with an area's slug to scope the query. For sort, prefix a field with - for descending order (e.g. -published_at) or omit it for ascending.

Query Categories and Areas:

{# Fetch Categories for a specific Area #}
{% set blog_categories = categories({'area': 'blog'}).get() %}

{# Fetch a specific structural Area #}
{% set portfolio_area = areas({'slug': 'portfolio'}).first() %}