Developer Templates and View Data

Templates and View Data

Every theme template receives a rich, pre-assembled set of variables — the content, site settings, navigation, media and SEO data. This article is the reference for that data and for the rendering rules templates should follow.

How a template is chosen

For content of type page on a site with theme mytheme, Laravix renders themes.mytheme::page.show.

That namespace resolves against your theme first and the default theme second, so the view "exists" as long as either theme provides it. Only when neither does — an unknown content type, say — does Laravix fall back to themes.mytheme::default, which resolves the same way. The same convention applies to every content type, including plugin types.

In practice: to change how posts look, add post/show.blade.php to your theme. To leave them alone, add nothing. See Theme Structure.

Available variables

Assembled by Laravix\Cms\Services\PageDataBuilder and the CMS controller:

Variable Type Contents
$content Content The content being rendered, with fields and taxonomies loaded
$site Site The current site
$seo array title, description, og_image_url, noindex, canonical — with content-over-settings fallbacks already applied
$settings Collection All site settings as key ⇒ value
$navigations array Header/footer menu items, already localized for the current language
$navDesign array The design values from the navigation Design tabs
$logoMedia, $faviconMedia ?Media The logo and favicon from settings, resolved to models
$mediaMap Collection id ⇒ Media map of every media referenced by the page
$navPages Collection Published pages/archives of the current locale (id, title, slug, is_homepage) — for building simple menus
$archivePosts ?Collection On archive content only: published posts, newest first
$grapesjsHtml ?string The visual builder's HTML, already hydrated (post lists filled in, plugin hydrators applied)
$defaultLocale, $currentLocale string Locale codes
$alternates Collection locale ⇒ absolute URL of published translations (for hreflang)
$systemFieldKeys array Keys of code-registered fields — handy to separate them from ad-hoc fields
$appearance Collection Per-page appearance overrides. Currently always empty — the default layout reads it for background colour, text colour and a custom CSS class, so a template that uses it must tolerate empty values
$bgMedia ?Media Background image for the page. Currently always null, read by the default layout alongside $appearance

Working with media

Media models expose $media->url (the original) and $media->variantUrl(ImageVariant::LARGE) for resized variants (THUMBNAIL, MEDIUM, LARGE, OG, FAVICON, FULL — see Laravix\Cms\Enums\ImageVariant). Always render the smallest variant that fits the slot.

Working with fields

@php $fields = $content->fields->pluck('value', 'key'); @endphp
{{ $fields->get('excerpt') }}

Theme assets

Two helpers turn a file into a URL, both on Laravix\Cms\Laravix:

{{-- The stylesheet bundled with the core, from public/vendor/laravix/ --}}
<link rel="stylesheet" href="{{ \Laravix\Cms\Laravix::asset('app.css') }}">

{{-- A file your theme built into themes/{theme}/dist/ --}}
@if ($themeStylesheet = \Laravix\Cms\Laravix::themeAsset('app.css', $site->theme))
    <link rel="stylesheet" href="{{ $themeStylesheet }}">
@endif

themeAsset() takes the file name and the theme key, and returns null when the file isn't in that theme's dist/ — so always guard it as above rather than printing it straight into an attribute. The URL it returns ends with a ?v= stamp derived from the file's modification time, which busts the browser cache whenever you rebuild.

Both resolve to real files under public/, which for themes means the public/themes/{theme} symlink created by php artisan laravix:theme:link. If a theme stylesheet silently doesn't load, that link is the first thing to check.

Rendering builder content

Content designed in the visual builder arrives as $grapesjsHtml. Content built from classic blocks arrives as the $content->blocks array. The core ships a partial that handles both, including the JavaScript that sliders, tabs, countdowns and custom code blocks need:

@include('laravix::cms.builder-content')

The default theme's page/show.blade.php does exactly this when builder content exists, and falls back to a plain title-and-fields layout otherwise. If you render blocks yourself instead, each entry of $content->blocks is ['type' => ..., 'data' => [...]] and maps to your theme view blocks/{type}.blade.php, which receives the block's data plus $mediaMap.

URLs and languages

Build links to other content with $content->path($defaultLocale) — it handles the homepage, route prefixes and locale prefixes. In layouts, emit alternates:

@foreach ($alternates as $altLocale => $altUrl)
    <link rel="alternate" hreflang="{{ $altLocale }}" href="{{ $altUrl }}">
@endforeach

SEO contract

Layouts should honor the $seo array: put $seo['title'] in <title>, output the description and canonical link, emit noindex,nofollow robots meta when $seo['noindex'] is true, and use $seo['og_image_url'] for Open Graph. The default theme's layouts/app.blade.php is a complete reference implementation, including Open Graph, Twitter cards and JSON-LD.

Laravix Documentation · 25.08.2026
Star on GitHub