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 and auth/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