License Key Required
No license key entered.
Enter or update your key with php artisan health:license <key>,
or purchase one at scriptgain.com.
Portal
components.layouts.portal
Compiled PHP
What Blade turns your template into. This is what the syntax check parses.
Loading…
Available Variables And Components
A guide to what this template can use, derived from the shipped source. Click any item to insert it at your cursor. It is a helpful reference, not a runtime guarantee.
Always Available
- Validation error bag. Always present. Pairs with @error('field').
In This Template
- Heading.
- Nav.
- Portal Name.
- Subtitle.
- The page title set by the controller.
Drop any of these in. Click to insert the opening tag at your cursor.
General
Admin Panel
Layouts
Records
Site (Public)
Common Blade
- Print a value, safely escaped. The default choice.
- Print raw HTML. Only for content you trust.
- Show something conditionally.
- Loop over a collection.
- Loop, with a fallback when the collection is empty.
- Show a validation message for a field.
- A small block of PHP. Never on line 1. Keep logic out of templates.
- A comment that never reaches the browser.
Civic Helpers
- Build a URL to a named route, e.g. a department page.
- Link to a single news post.
- Turn a stored upload path into a public URL.
- A cache-busted URL for a bundled asset.
- Read a config value, e.g. the site width class.
- Build an absolute URL to a path.
No History Yet
Every save, revert, and reset of this template is recorded here, with a one-click way back to any of them.
The Template That Shipped With The Product
Read only. This is what Reset To Default puts back.
@props([
'title' => null,
'portalName' => 'Portal',
'nav' => [],
'heading' => null,
'subtitle' => null,
])
{{-- Shared chrome for the teacher and student/guardian portals. Self-contained
head (Tailwind CDN + accent tokens + health.css) so it renders identically to
the rest of the site without a build step. --}}
<!DOCTYPE html>
<html lang="en" class="h-full">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex, nofollow">
<title>{{ $title ? $title . ' – ' . config('brand.name') : config('brand.name') }}</title>
<link rel="icon" type="image/svg+xml" href="{{ route('favicon.svg') }}">
<link rel="icon" type="image/png" sizes="64x64" href="{{ route('favicon.png') }}">
<x-tailwind-cdn />
<x-accent-style />
</head>
<body class="h-full min-h-full bg-slate-50">
<a href="#main-content" class="skip-link">Skip To Main Content</a>
<div class="min-h-full flex flex-col">
<div class="h-0.5 bg-gradient-to-r from-brand-700 via-seal-500 to-brand-700"></div>
{{-- Top bar --}}
<header class="bg-chrome text-slate-200">
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex h-14 items-center justify-between gap-4">
<div class="flex items-center gap-2.5 min-w-0">
<span class="inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-white/10 text-white ring-1 ring-white/15">
<x-icon name="academic-cap" class="w-4 h-4" />
</span>
<div class="min-w-0 leading-tight">
<span class="block truncate font-semibold text-white">{{ config('brand.name') }}</span>
<span class="block truncate text-[11px] uppercase tracking-[0.14em] text-slate-400">{{ $portalName }}</span>
</div>
</div>
<div class="flex items-center gap-3">
@auth
<span class="hidden sm:block text-sm text-slate-300">{{ auth()->user()->name }}</span>
@endauth
<form method="POST" action="{{ route('logout') }}">
@csrf
<button type="submit" class="inline-flex items-center gap-1.5 rounded-lg border border-transparent px-3 py-1.5 text-sm font-medium text-slate-200 hover:border-white/20 hover:bg-white/5 transition">
<x-icon name="lock" class="w-4 h-4" /> Sign Out
</button>
</form>
</div>
</div>
</div>
</header>
{{-- Portal nav --}}
@if (! empty($nav))
<nav class="bg-white border-b border-slate-200" aria-label="Portal">
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
<ul class="flex gap-1 overflow-x-auto">
@foreach ($nav as $item)
<li>
<a href="{{ $item['href'] }}"
@if (! empty($item['active'])) aria-current="page" @endif
class="inline-flex items-center gap-2 whitespace-nowrap border-b-2 px-3 py-3 text-sm font-medium transition {{ ! empty($item['active']) ? 'border-brand-600 text-brand-700' : 'border-transparent text-slate-600 hover:border-slate-300 hover:text-slate-900' }}">
@if (! empty($item['icon']))<x-icon :name="$item['icon']" class="w-4 h-4" />@endif
{{ $item['label'] }}
@if (! empty($item['badge']))
<span class="ml-1 inline-flex min-w-[1.25rem] items-center justify-center rounded-full bg-brand-600 px-1.5 text-[11px] font-semibold text-white">{{ $item['badge'] }}</span>
@endif
</a>
</li>
@endforeach
</ul>
</div>
</nav>
@endif
<main id="main-content" class="flex-1 py-8">
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
@if ($heading)
<div class="mb-6">
<h1 class="font-display text-2xl font-semibold text-slate-900">{{ $heading }}</h1>
@if ($subtitle)<p class="mt-1 text-slate-500">{{ $subtitle }}</p>@endif
</div>
@endif
@if (session('status'))
<div class="mb-6 rounded-lg bg-emerald-50 px-4 py-3 text-sm text-emerald-800 ring-1 ring-emerald-200">{{ session('status') }}</div>
@endif
@if (session('warning'))
<div class="mb-6 rounded-lg bg-amber-50 px-4 py-3 text-sm text-amber-800 ring-1 ring-amber-200">{{ session('warning') }}</div>
@endif
{{ $slot }}
</div>
</main>
<footer class="border-t border-slate-200 py-6">
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 text-xs text-slate-400">
{{ config('health.site.name', config('brand.name')) }} · Powered by {{ config('brand.name') }}
</div>
</footer>
</div>
</body>
</html>
Blade In One Screen
The directives you will use most.
- Print a value, escaped. Safe by default.
- Print raw HTML. Only for content you trust.
- Show something conditionally.
- Loop over a collection.
- Use a shared component. Every component in Shared Components is available.
- A comment that never reaches the browser.
{{ $variable }}
{!! $html !!}
@if / @else / @endif
@foreach / @endforeach
<x-card>
{{-- comment --}}
House Rules
Follow these and your edits will survive updates.
-
Never start line 1 with
@php. Blade mis-parses it and the page fails. The editor refuses to save it. - Keep logic out of templates. If you need a calculation, it belongs in a composer or component class, not here.
- The shipped file is never modified. Reset To Default always gets you back.
- Every save is versioned. You can revert to any earlier version in one click.
- Press Tab inside the editor to indent rather than jump to the next field.