JReviews logo Docs
Menu
Version

Custom Field PHP Formatting

PHP based formatting provides a lot of flexibility for customizing the output of custom fields.

Overview

Development & Support
Customizations are not included with support. We provide this information to make it easier for developers to extend the functionality. From time to time we may have some availability for custom work. Get in touch to see if there's an opportunity to work together.

Output formatting for custom fields refer to the field output, rather than input presentation in forms. There are three types of customizable output formatting available:

Output Format

Allows using HTML and pre-defined tags to build simple layouts. Works in both standard and Early Access modes.

Blade Template Formatting (Early Access)

Template-based system using Blade syntax. Only available when the Early Access listing detail page is enabled.

PHP Based Formatting (Standard Mode)

Provides access to raw data for the field and the associated entry (listing or review) so you can create complex logic and mould the output to your specific needs. Only available when Early Access is disabled.

Mutually Exclusive Systems
When Early Access is OFF, the Advanced Settings show "PHP output format" and "Field output template" options. When Early Access is ON, these are replaced by "Blade template code" and "Field output Blade template" options. Any custom code in the PHP format settings will be ignored when Early Access is enabled.

Choosing a Formatting Approach

Approach When to Use Mode
Output Format Simple HTML layouts with tags like {fieldtext}, {listing_id} Both
Blade Templates Complex logic with Early Access listing detail page enabled Early Access
PHP Format Complex logic when Early Access is disabled Standard

The formatting options are located in Custom Fields → Edit Field → Advanced Settings tab.

Blade Template Formatting (Early Access)

Prerequisite
The Early Access listing detail page must be enabled for Blade template formatting to work. Enable it in the JReviews administration under Early Access settings.

When Early Access is enabled, the Advanced Settings tab shows two new options for custom field output:

  • Blade template code - Code editor for writing Blade syntax directly (replaces "PHP output format")
  • Field output Blade template - Dropdown to select pre-made Blade template files (replaces "Field output template")

Blade Template Code Setting

The "Blade template code" setting provides an inline editor where you can write Blade syntax directly. This is convenient for simpler formatting requirements.

Basic Example

<div class="custom-field-output">
    {{ $data }}
</div>

With Conditionals

@if ($data)
    <span class="field-value">{{ $data }}</span>
@else
    <span class="no-value">Not specified</span>
@endif

Field Output Blade Template Setting

For more complex formatting, you can create template files and select them from the "Field output Blade template" dropdown.

Template files should be placed in your custom theme's fields_phpformat/ folder:

Joomla

templates/jreviews_overrides/views/themes/{your-theme}/fields_phpformat/my-template.blade.php

WordPress

jreviews_overrides/views/themes/{your-theme}/fields_phpformat/my-template.blade.php
Naming Convention
Use hyphens in template names and the `.blade.php` extension. For example: `business-hours.blade.php`, `inventory-list.blade.php`.

After creating a template file, clear the file registry in JReviews administration to make it appear in the dropdown.

Available Variables (Blade)

The following variables are available within Blade templates:

Variable Description
$data (mixed) For FormBuilder fields, JSON is already decoded into an array. For regular fields, equals $value.
$value (mixed) Raw field value (same as PHP format $value)
$field (array) Field configuration data
$listing (object) Eloquent Listing model instance (for listing custom fields). Access properties with arrow syntax: $listing->title, $listing->featured
$comment (object) Eloquent Comment model instance (for review custom fields). Access properties with arrow syntax: $comment->id, $comment->rating
$route (object) Current route context
$attributes (object) HTML attributes bag
$data vs $value
For **FormBuilder fields** that store JSON, `$data` is pre-parsed into an array ready to iterate. For **regular fields** (text, select, etc.), `$data` equals `$value` - use either one. When in doubt, use `$value` for simple fields and `$data` for FormBuilder fields.

Blade Syntax Reference

Variable Output

{{ $data }}                    {{-- Escaped output --}}
{!! $data !!}                  {{-- Unescaped HTML output --}}

Conditionals

@if ($data)
    ...
@elseif ($condition)
    ...
@else
    ...
@endif

@isset($listing->title)
    {{ $listing->title }}
@endisset

@empty($data)
    No data available
@endempty

Loops

@foreach ($data as $item)
    <div>{{ $item['name'] }}</div>
@endforeach

@forelse ($data as $item)
    <div>{{ $item['name'] }}</div>
@empty
    <p>No items found</p>
@endforelse

PHP Blocks

@php
    $total = count($data);
    $formatted = number_format($total);
@endphp

<span>Total: {{ $formatted }}</span>

Props Declaration

When creating template files, declare expected variables at the top:

@props(['data', 'listing' => null, 'comment' => null, 'route' => null])

<div data-formbuilder="inventory">
    @foreach ($data as $item)
        <div>{{ $item['name'] }}</div>
    @endforeach
</div>

Blade Examples

Business Hours (Blade)

@php
$periods = $data['periods'] ?? $data;
$OpeningHours = (new OpeningHours())->addPeriods($periods);
$days = $OpeningHours->twentyfour(false)->getOrderedPeriods();
@endphp

<ul data-formbuilder="businesshours">
    @foreach (range(1,7) as $dayNumber)
    <li>
        <span data-businesshours-day="{{ $dayNumber }}">
            @lang('site.temporal.days_short.'.$dayNumber)
        </span>
        <span data-businesshours-hour-period>
            @isset($days[$dayNumber])
                {{ implode(', ', $days[$dayNumber]) }}
            @else
                @lang('site.status.closed')
            @endisset
        </span>
    </li>
    @endforeach
</ul>

Inventory List (Blade)

@props(['data', 'listing' => null])

<div data-formbuilder="inventory" class="grid gap-2">
    @foreach ($data as $item)
        <div class="flex justify-between p-2 border rounded">
            <span>{{ $item['name'] }}</span>
            <span class="font-bold">${{ number_format($item['price'], 2) }}</span>
        </div>
    @endforeach
</div>

Conditional Based on Listing Data (Blade)

@if ($listing && $listing->featured)
    <div class="featured-badge">
        <span>{{ $value }}</span>
        <span class="badge">Featured</span>
    </div>
@else
    <span>{{ $value }}</span>
@endif

PHP Format System (Standard Mode)

Standard Mode Only
The PHP format system is only available when the Early Access listing detail page is **disabled**. If you plan to enable Early Access, customizations in these settings will need to be migrated to the Blade format options.

When Early Access is disabled, the Advanced Settings tab shows the traditional PHP formatting options:

  • PHP output format - Code editor for writing PHP code directly
  • Field output template - Dropdown to select PHP template files
PHP Based Formatting Options
PHP Based Formatting Options

PHP Output Format Setting

With the PHP Output Format setting you can add write PHP code directly within the field's settings using the PHP editor.

It's important to note that the editor is ready for you to write PHP code without having to add an opening <?php tag. You can pass all your output into a variable and return it, or you can echo your variables.

Both of these are valid within the built-in editor:

Echoed Output

?>
<span>Label:</span> <span><?php echo $text; ?></span>

When using this option, you need to take into account that there is already an opening php tag, so if you want to add text or HTML code, you need to close it first.

Returned Output

return "<span>Label:</span> <span>{$text}</span>";

Field Output Template Setting

With template formatting you can create a custom template with your custom code and add the name of the template in the Template Name setting. Don't include the file extension, just the name.

While this approach requires a bit of extra work to create the template, it's also much easier to work with if your custom code is longer than a few lines. Template formatting also allows sharing a single template with multiple custom fields.

Any template file you create for custom field formatting goes inside your custom theme's fields_phpformat folder in overrides.

Joomla

templates/jreviews_overrides/views/themes/{your-theme}/fields_phpformat/

WordPress

jreviews_overrides/views/themes/{your-theme}/fields_phpformat/

Available Variables (PHP Format)

The following variables are available within the PHP format scope:

Variables Description
$name (string) custom field name.
$entry (array) associated listing or review.
$listing (array) same as $entry and only available in listing custom fields.
$review (array) same as $entry and only available in review custom fields.
$field (array) field data
$fields (array) fields data for $entry
$value (mixed) selected field values.
$text (mixed) current field text.
$image (mixed) current field option image names
$output (array) standard output
$params (array) contains contextual page info useful to write custom logic. Keys in the array include route, controller, action, viewVars, viewSuffix, listview.
  • $value, $text and $image variables are arrays for checkboxes and multiple select custom fields, and strings for all other fields.
  • $value and $text are identical for fields without pre-defined options (e.g. text, decimal, integer, etc)
  • The CustomFieldsHelper PHP class is available in the PHP format scope by using the $CustomFields object instance.

If you want to inspect the contents of any of the above variables you can use either the prx and dd functions in the code editor:

// Dumps the contents of the variable and stops code execution
dd($params);
// Outputs the contents of the variable and continues
prx($params);

Comparison: Blade vs PHP Format

The following table highlights the key differences between the two formatting systems:

Aspect Blade Templates (Early Access) PHP Format (Standard)
Mode Early Access ON Early Access OFF
Data variable $data (FormBuilder) or $value (regular fields) $text (raw string)
Output syntax {{ $var }} <?php echo $var; ?>
Conditionals @if ... @endif <?php if (...): ?> ... <?php endif; ?>
Loops @foreach ... @endforeach <?php foreach (...): ?> ... <?php endforeach; ?>
FormBuilder JSON Already decoded in $data Need json_decode($text, true)
File extension .blade.php .thtml
Review variable $comment (model) $review (array)
Listing access $listing->title (model) $listing['Listing']['title'] (array)

Side-by-Side Example

PHP Format (Standard Mode)

<?php
$inventory = json_decode($text, true);
?>
<div class="jrTableGrid">
   <?php foreach ($inventory AS $item): ?>
      <div class="jrRow">
         <div class="jrCol"><?php echo $item['name'];?></div>
         <div class="jrCol">$<?php echo $item['price'];?></div>
      </div>
   <?php endforeach;?>
</div>

Blade Template (Early Access)

@props(['data', 'listing' => null])

<div data-formbuilder="inventory" class="grid">
   @foreach ($data as $item)
      <div class="row">
         <div>{{ $item['name'] }}</div>
         <div>${{ $item['price'] }}</div>
      </div>
   @endforeach
</div>

Migration Guide

This section helps you migrate custom field formatting from PHP format to Blade templates when enabling Early Access.

Understanding the Scope

Who needs to migrate:

  • Only users who have added custom code in individual custom field's Advanced Settings using the "PHP output format" editor or "Field output template" dropdown
  • Fields without custom code in these settings continue working normally - no migration needed
  • This is a per-field migration, not a site-wide change

What happens when you enable Early Access:

  • "PHP output format" and "Field output template" settings are ignored
  • Affected fields gracefully fall back to their "Output format" setting (the simpler HTML/tags option)
  • No errors occur, but custom formatting is lost until migrated
  • Fields without customizations in these settings are unaffected

Prerequisites

Before migrating:

  1. Backup your site - Ensure you have complete backups that can be restored
  2. Test on staging first - Never enable Early Access on production without testing
  3. Identify affected fields - Check each custom field's Advanced Settings for code in "PHP output format" or a selection in "Field output template"
  4. Document your custom code - Copy the existing PHP code for each affected field

Step-by-Step Conversion

  1. Identify fields with custom formatting

    • Go to Custom Fields in JReviews administration
    • Open each field's settings and check the Advanced Settings tab
    • Note which fields have code in "PHP output format" or a selection in "Field output template"
  2. Copy existing PHP code

    • For each affected field, copy the custom PHP code for reference
    • Save it in a text file for the conversion process
  3. Convert to Blade syntax

  4. Enable Early Access (on staging first)

    • Enable the Early Access listing detail page in JReviews administration
  5. Add converted code

    • Open each affected custom field's settings
    • Go to the Advanced Settings tab
    • Paste the converted Blade code into "Blade template code", or
    • Create a .blade.php template file and select it from "Field output Blade template"
  6. Test thoroughly

    • View listings that use the custom fields
    • Verify the output matches your expectations
    • Test different scenarios (empty data, multiple values, etc.)

Common Patterns

PHP Format Blade Format
$text $data
$review $comment
json_decode($text, true) Use $data directly (already decoded)
<?php echo $var; ?> {{ $var }}
<?php if (...): ?> ... <?php endif; ?> @if (...) ... @endif
<?php foreach (...): ?> ... <?php endforeach; ?> @foreach (...) ... @endforeach
<?php ... ?> @php ... @endphp

AI-Assisted Migration

You can use AI to help convert your PHP format code to Blade syntax. Copy the prompt below, paste it into Claude, ChatGPT, or your preferred AI assistant, and add your PHP code at the end.

AI Migration Prompt:

I need help converting JReviews custom field PHP format code to the new Blade template format.

## Context
When JReviews Early Access is enabled, the custom field formatting system changes:
- OLD: PHP format with `$text` variable containing raw data (JSON string for FormBuilder fields)
- NEW: Blade templates with `$data` or `$value` variable

## Variable Mappings

PHP Format (old) → Blade Format (new):
- `$text` → `$value` for regular fields, `$data` for FormBuilder fields (already decoded array)
- `$value` → `$value` (raw value, same in both)
- `$entry` → `$listing` or `$comment` (depending on context)
- `$review` → `$comment` (renamed, now an Eloquent model)
- `$field` → `$field` (same)

## IMPORTANT: Model Access Syntax

In Blade templates, `$listing` and `$comment` are Eloquent model instances, NOT arrays.

WRONG (array syntax):
- `$listing['title']`
- `$listing['featured']`
- `$comment['id']`

CORRECT (model syntax):
- `$listing->title`
- `$listing->featured`
- `$comment->id`

## Common Listing Properties
- `$listing->id` - Listing ID
- `$listing->title` - Listing title
- `$listing->alias` - URL alias
- `$listing->summary` - Summary text
- `$listing->description` - Full description
- `$listing->featured` - Featured status (boolean)
- `$listing->created` - Created date
- `$listing->updated` - Modified date

## Common Comment Properties
- `$comment->id` - Comment/Review ID
- `$comment->rating` - User rating
- `$comment->title` - Review title
- `$comment->comment` - Review text
- `$comment->created` - Created date

## Syntax Conversions

- `<?php ?> blocks` → `@php @endphp` (only when needed)
- `<?php echo $var; ?>` → `{{ $var }}`
- `<?php if (): ?> <?php endif; ?>` → `@if () @endif`
- `<?php foreach (): ?> <?php endforeach; ?>` → `@foreach () @endforeach`
- `json_decode($text, true)` → Use `$data` directly (already parsed for FormBuilder fields)

## Your Code to Convert

Please convert this PHP format code to Blade template format:

[PASTE YOUR PHP FORMAT CODE HERE]

After the AI converts your code, test it thoroughly on a staging site with Early Access enabled before using it on production.

Real Migration Examples

Inventory Field Migration

Before (PHP Format)

<?php
$inventory = json_decode($text, true);
?>
<div class="jrTableGrid">
   <?php foreach ($inventory AS $item): ?>
      <div class="jrRow">
         <div class="jrCol"><?php echo $item['name'];?></div>
         <div class="jrCol">$<?php echo $item['price'];?></div>
      </div>
   <?php endforeach;?>
</div>

After (Blade)

@props(['data', 'listing' => null])

<div data-formbuilder="inventory" class="grid">
   @foreach ($data as $item)
      <div class="row flex justify-between">
         <div>{{ $item['name'] }}</div>
         <div>${{ $item['price'] }}</div>
      </div>
   @endforeach
</div>

Authentication Conditional Migration

Before (PHP Format)

$auth = S2Object::make('auth');

return $auth->guest ? false : $output;

After (Blade)

@auth
    {{ $data }}
@endauth

PHP Format Examples

The following examples apply to the PHP format system when Early Access is disabled.

Show Default Output

To show the default field output, return the $output array. This is useful when creating conditional logic to show a custom output in some instances, otherwise show the default output.

return $output;

Hide Output

To completely hide the field output, return a boolean false or a empty string.

return false;

Authentication Conditionals

For authentication conditionals, based on the logged in user, we use the auth service.

Hide Output for Guests

$auth = S2Object::make('auth');

return $auth->guest ? false : $output;

Show Log in Message to Guests

$auth = S2Object::make('auth');

return $auth->guest ? "Log in to view this field" : $output;

Show Ouput if More than One Option Selected

For checkbox and multiple select lists

$count = is_array($output) ? count($output) : 1;

return $count > 1 ? $output : false;

Custom Images For Select List using Bannner

The code below goes inside a banner custom field, and we use the output of a jr_city field to check the selected options.

$city = $CustomFields->fieldValue('jr_city',$entry);

switch($city) {
   case 'san-francisco':
      $banner = "sanfrancisco.jpg";
   break;
   case 'new-york':
      $banner = "newyork.jpg";
   break;
   default: // All other cities display the default banner output
       return $output;
   break;
}

$banner = '/media/banners' . $banner;

return "<img src=".$banner." />";

Show Output Only When Another Selected

Checkbox and Multiple Select Lists

In this example, the field output is only shown when the email value is checked in the jr_checkbox field.

$checkboxes = $CustomFields->fieldValue('jr_checkbox',$entry);

return in_array('email',$checkboxes) ? $output : false;

Radiobutton and Single Select List

$selected = $CustomFields->fieldValue('jr_radio',$entry);

return $selected == 'yes' ? $output : false;

Concatenate Fields

Using a banner custom field to concatenate values with commas, or any other specific format, but not all fields are required.

$out = [];
$names = [
  'jr_addressline1',
  'jr_addressline2',
  'jr_town',
  'jr_city',
  'jr_county',
  'jr_postcode'
];
foreach ($names AS $name)
{
   $out[] = $CustomFields->fieldValue($name, $entry);
}
$out = array_filter($out);
$out = implode(', ', $out);
return $out != '' ? $out : false;

Hide Output Until Click

The code below can be used with a text-based fields or fields with single choice selections (single select, radiobutton).

return '<span class="jrButton" data-value="'.$text.'" onclick="jQuery(this).html(jQuery(this).data(\'value\')).removeClass(\'jrButton\');">Click to reveal info</span>';
$Routes = new RoutesHelper;
return $Routes->category($entry, $entry['Category']);
$Routes = new RoutesHelper;
$url = $Routes->category($entry, array('return_url'=>'true'));
return sprintf('<a href="%s">Custom Text</a>',$url);
$Routes = new RoutesHelper;
return $Routes->myListings($entry['User']['name'], $entry['User']['user_id']);

Calculate Totals Sales Based on Price and Volume

Using a banner custom field.

$price = $CustomFields->fieldValue('jr_price',$entry);
$volume = $CustomFields->fieldValue('jr_volume',$entry);
$total = $price * $volume;
return $total;

If one of the values is zero, you can display the default output of the banner instead, or if you prefer to hide the output, return false instead.

$price = $CustomFields->fieldValue('jr_price',$entry);
$volume = $CustomFields->fieldValue('jr_volume',$entry);
$total = $price * $volume;
return $total > 0 ? $total : $output;

Calculate Age Based on Birth Date

$bday = new DateTime($text);
$today = new DateTime();
$diff = $today->diff($bday);
return $diff->y;