Templates · Blade or Twig
In Vanilo Cloud, Blade and Twig templates can be used. The names of the templates are the same regardless of the chosen engine. The difference is the file extension. For example
auth/register.blade.php
for Blade andauth/register.twig
for Twig templates.The routes, base file names and the injected variables are identical for both engines.
Templates
As described at routing, every route endpoint will use a specific twig or blade template to render the page. Every template will receive several variables, that you can use to build the page.
Home Page
Path | Route | View |
---|---|---|
/ | shop.home |
home |
When opening the root url of a shop, the home
template gets rendered.
By default, there are no variables injected into this view.
If you need data (like categories or products) on your homepage, then you need to specify them in the config/vanilo.json file:
{
"cloud": {
"home": {
"inject": {
"products": "product.latest(4)",
"brands": "taxonomy.bySlug(brands)"
}
}
}
}
Refer to the Hick Script page to learn the available syntax for injection.
The example above will take the 4 latest products (created most recently) and the taxonomy "brands"
and inject them into the home view as $products
and $brands
variables:
{{-- home.blade.php --}}
<h2>Shop By Brand</h2>
@foreach($brands->getRootLevelTaxons() as $brand)
<h3><a href="{{ url_of($brand) }}">{{ $brand->name }}</a></h3>
@endforeach
<h2>Latest Products</h2>
@foreach($products as $product)
<article>
<h3><a href="{{ url_of($product) }}">{{ $product->title }}</a></h3>
<img src="{{ $product->getFirstMediaUrl('default', 'medium') ?: asset('/img/default/product_medium.jpg') }}" />
</article>
@endforeach
Taxon (Category) Page
Path | Route | View |
---|---|---|
/c/{taxonomy}/{taxon} | shop.taxon.show |
taxon/show |
/c/{taxonomy}/{parent}/{taxon} | shop.taxon.show.with-parent |
taxon/show |
The category page displays a single taxon, and - almost always - the products within that taxon.
The following variables are available in the taxon show template:
Variable | |
---|---|
$taxon |
The taxon that is currently being shown |
$products |
The collection of products within the taxon |
$filters |
The filters for the given page |
$taxonomies |
The collection of all taxonomies in the shop |
Product List
Path | Route | View |
---|---|---|
/p | shop.product.index |
product/index |
This page is rarely used, but can be useful for shops with a smaller number of products, or when there's no
need for categorization. The template receives the same variables as the taxon show page, but the $taxon
variable is
always null:
Variable | |
---|---|
$taxon |
NULL |
$products |
The collection of products |
$filters |
The filters for the given page |
$taxonomies |
The collection of all taxonomies in the shop |
Product Filtering
The filtering process starts with retrieving all products and dynamically generating filters.
User-selected filters are then applied to refine the product query, ensuring that only products matching the selected criteria will be displayed.
Product Page
Path | Route | View |
---|---|---|
/p/{slug} | shop.product.show |
product/show |
This page displays detailed information about the product.
The following variables are available on the product show template.
Variable | |
---|---|
$product |
The product |
$taxonomies |
The collection of all taxonomies in the shop |
$reviewSummary |
An instance of the ReviewSummary class, containing statistics about reviews |
$reviews |
The partial collection of reviews associated with the product see documentation |
The reviewSummary object has the following structure:
$reviewSummary->totalCount; // The total number of reviews
$reviewSummary->max; //The configured maximum rating, typically 5
$reviewSummary->stars(); // Returns an array with all the unique Star values
// [
// '1*' => Star,
// '2*' => Star,
// '3*' => Star,
// '4*' => Star,
// '5*' => Star
// ]
$star1 = $reviewSummary->stars()['1*']; // or:
$star1 = $reviewSummary->star(1); // Return the details of 1-Star reviews
$star1->star; // 1
$star1->outOf; // 5 (or the maximum configured)
$star1->ratings; // the number of 1-star ratings given
$star1->percent; // The percentage of 1-star ratings from all reviews
Cart
Path | Route | View |
---|---|---|
/cart [GET] | shop.cart.show |
cart/show |
/cart/{product} [POST] | shop.cart.add, $product |
redirects to the cart/show |
/cart/v/{masterProductVariant} [POST] | shop.cart.add-variant, $product |
redirects to the cart/show |
/cart/update/{cartItem} [POST] | shop.cart.update, $item |
redirects to the cart/show |
/remove/{cartItem} [POST] | shop.cart.delete, $item |
redirects to the cart/show |
Cart Show
This page is available at the GET /cart URL. If the cart is empty a warning message will be shown saying that products need to be added to the cart.
The following method,
Cart::getItems()
, returns a collection of all the products that have been added to the cart.
When looping through this collection, each individual product will be accessible.
Cart Update
When a product's quantity in the cart is updated, a notification message will inform the customer about the change.
Subsequently, the price and quantity will be adjusted based on the updated product quantity, and the total price will be recalculated accordingly.
Checkout
Path | Route | View |
---|---|---|
/checkout [GET] | shop.checkout.show |
checkout/show |
/checkout [POST] | shop.checkout.submit |
checkout/thankyou (successful) |
/checkout [POST] | shop.checkout.submit |
checkout/failed (error) |
The checkout consists of several pages, for data collection and validation, successful and failed checkout pages.
Show Checkout
This page is available at the GET /checkout
URL. If the cart is empty, then the $checkout
variable is false
,
which means that you should not display the checkout fields because, there's nothing to buy.
Empty Checkout Example:
{{-- checkout/show.blade.php --}}
<h1>Checkout</h1>
@if($checkout)
@include('shop::checkout._form')
@else
<div class="alert alert-warning">
<p>{{ __('Hey, nothing to check out here!') }}</p>
</div>
@endif
The following variables are available to the checkout show template.
Variable | |
---|---|
$checkout |
A Checkout object or false |
$billingCountries |
A collection of the available billing countries |
$shippingCountries |
A collection of the available shipping countries |
$paymentMethods |
The collection of the available payment methods for the current checkout |
$shippingMethods |
The collection of the available shipping methods for the current checkout |
In case the shopper submits an incomplete, or invalid checkout form, the checkout show form will be displayed again, along with the validation errors.
Successful Checkout
If a checkout was successfully submitted (POST /checkout
), then the checkout/thankyou
template will
be rendered.
The following variables are available to the checkout thankyou template.
Variable | |
---|---|
$order |
The just created order object |
$paymentRequest |
null or a payment request object that needs to be rendered |
The $order
object has the following attributes/methods:
Field | Details |
---|---|
number |
The order number, eg. "6VR-0SUJ-1YM9" |
total |
The order total eg. "199.90" |
taxes_total |
The total of the taxes on the order "49.90" |
shipping_total |
The total of the shipping fees on the order "7.90" |
status |
pending by default |
billpayer |
The billing address |
shipping_address |
The shipping address |
language |
The language of the order eg. "de" |
currency |
The currency of the order eg. "EUR" |
affiliate |
null or the stored affiliate id see Affiliate & Resellers Tracking |
reseller |
null or the stored affiliate id see Affiliate & Resellers Tracking |
The $order->billpayer
and $order->shipping_address
objects have the following fields:
Field | Details |
---|---|
email |
The email of the shopper for the respective order |
phone |
null or the shopper's phone for the order |
firstname |
The given name |
lastname |
The family name |
company_name |
null or the company name |
tax_nr |
null or the tax number when ordering for a company |
registration_nr |
null or the trade reg no. of the company |
country_id |
null or the country code eg. "NL" |
postalcode |
null or string eg. "2282 NP" |
city |
City eg. "Rijswijk" |
street_address (billing address only) |
Street address eg. "Tulpstraat 109." |
address (shipping address only) |
Street address eg. "Tulpstraat 109." |
address2 |
null or additional address details |
access_code |
null or code to access a PUDO (locker) or building |
Example:
{{-- checkout/thankyou.blade.php --}}
@extends('shop::layouts.default')
@section('title', __('We have received your order'))
@section('content')
<h1>Thank you</h1>
<div class="alert alert-success">
{!! __('Your order number is <strong>:number</strong>. Please refer to this number if you have questions or concerns regarding your order.', ['number' => $order->number]) !!}
</div>
@if(null !== $paymentRequest)
Renders the redirect script or payment form for the chosen online payment method
{!! $paymentRequest->getHtmlSnippet(['autoRedirect' => $paymentRequest->willRedirect()]); !!}
@else
This is the case when there's an offline payment method used.
Display some text to the user
@endif
@endsection
Failed Checkout
If a checkout submission (POST /checkout
) has failed due to server side errors, then the checkout/failed
template will
be rendered. This is a very rare case, but even at such errors, we don't want to leave the users in the dark, that's
why the info page gets rendered. Additionally, you can add integration code snippets for sending notifications about such
events.
The following variables are available to the checkout failed template.
Variable | |
---|---|
$reason |
An object that contains details about the error |
{{-- checkout/failed.blade.php --}}
@section('content')
<h1>{{ __('Sorry, your order could not be placed') }}</h1>
<div class="alert alert-warning">
<h3>
{{ isset($reason) ? $reason->publicMessage() : __('Unknown Reason') }}
</h3>
💡 {{ __('Tip') }}: {{ isset($reason) ? $reason->publicTipForRecovery() : __('Go back to the cart and try placing the order again') }}
</div>
@endsection
Auth
The auth consists of several publicly accessible pages, for data collection and validation.
Path | Route | View |
---|---|---|
/u/register [GET] | shop.register |
auth/register |
/u/register [POST] | shop.register.submit |
redirects to the config.cloud.urls.after_registration (successful) |
/u/login [GET] | shop.login |
auth/login |
/u/login [POST] | shop.login |
redirects to the config.cloud.urls.after_login (successful) |
/u/logout [POST] | shop.logout |
redirects to the config.cloud.urls.after_logout (successful) |
/u/password/forgot [GET] | shop.password.forgot.show |
auth/forgot_password |
/u/password/forgot [POST] | shop.password.forgot.store |
redirects back with a status message |
/u/password/reset/{token} [GET] | shop.password.reset.show |
auth/reset_password |
/u/password/reset/{token} [POST] | shop.password.reset.store |
redirects to the config.cloud.urls.after_password_reset (successful) |
By default, a successful registration, login or logout will redirect to the home page unless a custom page is specified in config/vanilo.json
.
Example for custom URLs:
{
"cloud": {
"urls": {
"after_login": "/u/account",
"after_registration": "/u/account",
"after_logout": "/",
"after_password_reset": "/"
}
}
}
Auth Registration
The auth/register
template displays a form allowing users to register.
Validation rules for the registration form fields:
Field | Details |
---|---|
name |
required, string, min:5, max:255 This field must be filled out; it cannot be left blank The input must be a text string The name must be at least 5 characters long The name can be at most 255 characters long |
email |
required, string, email, max:255, unique:users This field must be filled out; it cannot be left blank The input must be a text string The input must be a valid email address format (e.g., [email protected]) The email can be at most 255 characters long The email must be unique |
code |
code, nullable This field can be left blank; it is optional |
password |
required, string, confirmed, min:6 This field must be filled out; it cannot be left blank The input must be a text string The input must be confirmed by re-entering the same value The password must be at least 6 characters long |
Auth Login
The auth/login
template displays a form allowing existing users to sign in.
Validation rules for the login form fields:
Field | Details |
---|---|
email |
required, string This field must be filled out; it cannot be left blank The input must be a text string |
password |
required, string This field must be filled out; it cannot be left blank The input must be a text string |
After 5 incorrect login attempts, a message notifies the user about the waiting period before they can try logging in again.
Auth Forgot Password
The auth/forgot_password
template displays a form where users can request a password reset via email.
Validation rules for the forgot password form field:
Field | Details |
---|---|
email |
required, string, email This field must be filled out; it cannot be left blank The input must be a text string The input must be a valid email address format (e.g., [email protected]) |
Entering an email address not found in the database triggers a validation message stating that no user with that email exists.
Entering an existing email address triggers a message indicating that an email has been sent to that address.
Auth Reset Password
The auth/reset_password
template displays a form where users can update their password.
The following variables are available in the reset password template:
Variable | |
---|---|
$token |
Unique generated identifier |
Validation rules for the reset password form fields:
Field | Details |
---|---|
token |
required This field must be filled out; it cannot be left blank |
email |
required, email This field must be filled out; it cannot be left blank The input must be a valid email address format (e.g., [email protected]) |
password |
required, confirmed, min:8 This field must be filled out; it cannot be left blank This field must be confirmed The password must be at least 8 characters long |
Account
The account includes several pages that are not publicly accessible, intended for data collection and validation purposes.
Path | Route | View |
---|---|---|
/u/account [GET] | shop.account.overview |
account/overview |
/u/orders [GET] | shop.account.orders |
account/orders |
/u/orders/{order} [GET] | shop.account.order.show, $order |
account/order |
/u/security [GET] | shop.account.security |
account/security |
/u/security [POST] | shop.account.security |
redirects to the account/overview |
/u/address [GET] | shop.account.address.index |
account/address/index |
/u/address/create?type=billing [GET] | shop.account.address.create, ['type' => 'billing'] |
account/address/create |
/u/address/create?type=shipping [GET] | shop.account.address.create, ['type' => 'shipping'] |
account/address/create |
/u/address [POST] | shop.account.address.store |
redirects to the account/address/index |
/u/address/{address}/edit [GET] | shop.account.address.edit, $address->id |
account/address/edit |
/u/address/{address} [POST] | shop.account.address.update', $address |
redirects to the account/address/index |
/u/address/{address} [POST] | shop.account.address.destroy', $address->id |
redirects to the account/address/index |
Account Overview
The following variables are available in the account overview template:
Variable | |
---|---|
$orders |
It takes 20 of the latest open orders |
Account Orders
The following variables are available in the account overview template:
Variable | |
---|---|
$orders |
It processes all the orders and paginates them, displaying 20 items per page |
Account Order
The account/order
template will display the order item corresponding to the given ID.
The following variables are available in the account order template:
Variable | |
---|---|
$order |
Displays the current order |
Account Security
The account/security
template will display a form where the currently authenticated user can update their password.
Validation rules for the account security form fields:
Field | Details |
---|---|
email |
required, email This field must be filled out; it cannot be left blank The input must be a valid email address format (e.g., [email protected]) |
password |
required This field must be completed with the old password |
new_password |
required, confirmed, min:8 This field must be filled out; it cannot be left blank The input must be confirmed by re-entering the same value The password must be at least 8 characters long |
Account Address
The following variables are available in the account address template:
Variable | |
---|---|
$addresses |
Displays all of the current user's billing and/or shipping addresses. |
Account Address Create
The account/address/create
template will display a form where the currently authenticated user can register a new billing and/or shipping address.
Common validation rules for both the account creation billing and shipping form fields:
Field | Details |
---|---|
email |
sometimes, nullable, email, max:255 The field is validated only if it is present in the input The field can be null; it is not required to have a value The field must be a valid email address The field value must not exceed 255 characters |
phone |
sometimes, nullable, string, max:255 The field is validated only if it is present in the input The field can be null; it is not required to have a value The field must be a string The field value must not exceed 255 characters |
address |
required, string, max:255 This field must be filled out; it cannot be left blank The input must be a text string The field value must not exceed 255 characters |
address2 |
sometimes, nullable, string, max:255 The field is validated only if it is present in the input The field can be null; it is not required to have a value The field must be a string The field value must not exceed 255 characters |
city |
sometimes, nullable, string, max:255 The field is validated only if it is present in the input The field can be null; it is not required to have a value The field must be a string The field value must not exceed 255 characters |
postalcode |
sometimes, nullable, string, max:12 The field is validated only if it is present in the input The field can be null; it is not required to have a value The field must be a string The field value must not exceed 12 characters |
country_id |
required, string, size:2, exists:countries,id This field must be filled out; it cannot be left blank The field must be a string The field must have a length of exactly 2 characters. The field's value must exist in the countries table's id column |
province_id |
sometimes, nullable, integer, exists:provinces,id The field is validated only if it is present in the input The field can be null; it is not required to have a value The field must be an integer Field value must exist in provinces table's id column |
type |
required, AddressType::BILLING, AddressType::SHIPPING This field must be filled out; it cannot be left blank The field type can be either Billing or Shipping |
access_code |
sometimes, nullable, string, max:255 The field is validated only if it is present in the input The field can be null; it is not required to have a value The field must be a string The field value must not exceed 255 characters |
Additional validation rules specific to the account creation billing
form fields, in addition to the common rules:
Field | Details |
---|---|
firstname |
sometimes, nullable, string, max:255 The field is validated only if it is present in the input The field can be null; it is not required to have a value The field must be a string The field value must not exceed 255 characters |
lastname |
sometimes, nullable, string, max:255 The field is validated only if it is present in the input The field can be null; it is not required to have a value The field must be a string The field value must not exceed 255 characters |
company_name |
sometimes, nullable, string, max:255 The field is validated only if it is present in the input The field can be null; it is not required to have a value The field must be a string The field value must not exceed 255 characters |
registration_nr |
sometimes, nullable, string, max:255 The field is validated only if it is present in the input The field can be null; it is not required to have a value The field must be a string The field value must not exceed 255 characters |
tax_nr |
sometimes, nullable, max:255 The field is validated only if it is present in the input The field can be null; it is not required to have a value The field value must not exceed 255 characters |
Additional validation rules specific to the account creation shipping
form fields, in addition to the common rules:
Field | Details |
---|---|
name |
sometimes, nullable, string, max:255 The field is validated only if it is present in the input The field can be null; it is not required to have a value The field must be a string The field value must not exceed 255 characters |
The AddressType is an Enum with the following values:
- billing
- shipping
Account Address Edit
The account/address/edit
template will display a form where the currently authenticated user can update their billing and/or shipping address.
The validation rules remain consistent whether updating an existing billing and/or shipping address or creating a new one.
Account Address Delete
It will remove the currently selected address
Fragment Rendering
If you are using Blade templates, it is possible to utilize its fragment rendering feature.
You can freely define fragments in your blade page:
<html>
<body>
<header>
@fragment('cart')
<i class="cart" />
<span class="badge">{{ cart()->itemCount() }}</span>
@endfragment
</header>
<main>
...
</main>
</body>
</html>
Afterwards, you can get the cart
fragment by appending the ?_fragment=cart
query parameter to the URL.
Fetching the URL this way return the given fragment only:
<i class="cart" />
<span class="badge">2</span>
If you pass a non-existent fragment, then the entire page will be returned.
Inject Global Variables
Besides the default variables injected into the views, it is also possible to inject data into every page.
For more details, see the Global Data Injection Section on the Configuration Page.
Template Helper Functions
There are several helper functions that you can use in your templates:
Function | What it does |
---|---|
format_price |
Formats a price based on the settings |
product_title |
Returns the title of a product, based on the config, regardless of its type |
url_of |
Returns the shop URL of various items like products, categories, orders, etc |
page_url |
Returns the URL of an info page |
add_to_cart_url |
Returns the add to cart URL of a product regardless of its type (plain product or variant) |
configuration_to_text |
Converts the configuration of a product, using the configuration spec |
md2html |
Converts Markdown text snippets to HTML |
cloudflare_turnstile |
Returns the HTML snippet of the Cloudflare captcha widget |