Product Details Page
URL: /{product-permalink} (dynamic)
Template: resources/views/template/product_details.blade.php
The most complex page in the system. Displays a single product with its full details, image gallery, variations, reviews, Q&A, and related products.
Page Variables
$page->misc->product — The Main Product Object
This is the central object for the page. Accessed as $page->misc->product.
| Property | Type | Description |
|---|---|---|
name |
string | Full product name |
itemNo |
string | SKU / item number |
normalPrice |
string | Regular price |
specialPrice |
string | Sale price (equals normalPrice if no discount) |
description |
string | Full HTML product description |
subtitle |
string | Short subtitle / tagline |
productPermalink |
string | URL slug |
productStock |
int | Current stock quantity |
availability |
int/bool | false or 0 = out of stock |
image |
string | Primary image URL |
review |
array | Array of review objects |
reviewDisplay |
string | Pre-rendered HTML star rating |
reviewCount |
int | Number of reviews |
addToCartUrl |
string | URL to add to cart |
askQuestionUrl |
string | URL for Q&A tab |
reviewUrl |
string | URL to write a review |
addTowishlistUrl |
string | URL to add to wishlist |
removeFromwishlistUrl |
string | URL to remove from wishlist |
discountPercent |
float | Discount percentage |
getUrl() |
method | Returns the canonical URL for this product |
title |
string | SEO title (may differ from name) |
Usage:
<h1>{{ $page->misc->product->name }}</h1>
<p>${{ tagPrice($page->misc->product->specialPrice ?? $page->misc->product->normalPrice) }}</p>
{!! $page->misc->product->description !!}
$page->misc->variation — Product Variations
A JSON string (or array) describing the product's variations (sizes, colors, etc.). Decode it to iterate:
@php
$jsonString = $page->misc->variation;
$data = json_decode($jsonString);
$variations = $data->variation ?? [];
@endphp
@if(twig_length($variations))
<h4>Choose a Variation:</h4>
@foreach($variations as $variation)
@php
$currentStock = $variation->currentStock ?? 0;
$isSoldOut = $currentStock <= 0;
$isDefault = $variation->isDefault ?? false;
@endphp
<div class="variation-option {{ $isDefault ? 'active' : '' }} {{ $isSoldOut ? 'sold-out' : '' }}">
<a href="{{ serverUrl() . '/' . $variation->permalink }}">
@foreach(twig_object_to_array($variation->variation ?? []) as $key => $value)
<span>{{ $key }}: {{ $value }}</span>
@endforeach
@if($isSoldOut)
<span class="text-danger">(Sold Out)</span>
@endif
</a>
</div>
@endforeach
@endif
Variation Object Properties:
| Property | Type | Description |
|---|---|---|
pid |
int | Product ID of this variation |
permalink |
string | URL path for this variation |
isDefault |
bool | Whether this is the currently selected variation |
currentStock |
int | Available stock for this specific variation |
variation |
object | Key-value pairs of variation attributes (e.g., {Size: "M", Color: "Red"}) |
$media — Image Gallery
An array of image objects for the product slider.
@foreach($media as $imageGallery)
@if(uploads()->has($imageGallery->fileName, 'product', $page->misc->product->itemNo))
@php $imgUrl = uploads()->get($imageGallery->fileName, 'product', $page->misc->product->itemNo); @endphp
<div class="gallery-slide">
<img src="{{ $imgUrl }}" alt="{{ $page->misc->product->name }}">
</div>
@endif
@endforeach
| Property | Type | Description |
|---|---|---|
$imageGallery->fileName |
string | The uploaded file name |
$imageGallery->isCoverImage |
bool | Whether this is the primary/cover image |
Other Page Variables
| Variable | Type | Description |
|---|---|---|
$totalQty |
int | Total product stock (may override productStock) |
$productPrice |
float | Current price (may override specialPrice) |
$config['facebookApplicationId'] |
string | Facebook App ID for social sharing |
$themes->product_background_color |
string | CSS color for image container background |
Sections Used
| Section | Description |
|---|---|
headmeta |
Open Graph meta tags for Facebook sharing (uses cover image) |
headtitle |
SEO title: {product.title} | {siteTitle} |
headlink |
Loads summernote CSS for review editor |
style |
Extensive page-specific styles |
content |
Main product layout with slider, details, variations, reviews, Q&A |
script |
Sliders, variation switcher, add-to-cart, review JS |
Example: Open Graph Head Meta
@section('headmeta')
@php
$imgSrcFb = $page->settings->noProductImage;
foreach($media as $imageGallery) {
if(uploads()->has($imageGallery->fileName, 'product', $page->misc->product->itemNo)) {
if($imageGallery->isCoverImage) {
$imgSrcFb = uploads()->get($imageGallery->fileName, 'product', $page->misc->product->itemNo);
}
}
}
@endphp
<meta property="fb:app_id" content="{{ $config['facebookApplicationId'] }}" />
<meta property="og:url" content="{{ $page->misc->product->getUrl() }}" />
<meta property="og:type" content="website" />
<meta property="og:title" content="{{ strip_tags($page->misc->product->name) }}" />
<meta property="og:description" content="{{ strip_tags($page->misc->product->description) }}" />
<meta property="og:image" content="{{ serverUrl() . $imgSrcFb }}" />
@parent
@endsection
Catalog Mode
When catalog mode is enabled ($page->settings->catalogMode == 1), the add-to-cart section should be hidden:
@if(!$page->settings->catalogMode)
<a href="{{ $page->misc->product->addToCartUrl }}" class="btn btn-primary">Add to Cart</a>
@endif
Partials Used on This Page
The product detail page includes several partials:
| Partial | Description |
|---|---|
@include('partial.productslider') |
Image gallery/slider for product photos |
@include('partial.productdetaildiv') |
Price, add-to-cart, wishlist, and quantity section |