Skip to content

Upgrading from 8.x to 9.x

This is a very big release, with a lot of changes. We try to limit breaking changes, but there are some... This guide will help you to upgrade your Sharp 8.x app to Sharp 9.x.

General

Get new assets, clear cache

This is true for every update: be sure to grab the latest assets and to clear the view cache:

bash
php artisan vendor:publish --tag=sharp-assets --force
php artisan view:clear

Update your composer.json

The command used to publish sharp's assets changed, you should update your composer.json:

json
{
    "scripts": {
      "post-update-cmd": [
        "@php artisan vendor:publish --tag=sharp-assets --force"
      ]
    }
}

INFO

Note that in addition to the command modification, we previously advice to put this script in the post-autoload-dump section, but this is not recommended anymore, move it to post-update-cmd instead.

Deprecated methods have been removed

  • Entity List: deprecated buildListFields() and buildListLayout() were removed, use buildList() instead
  • Form: deprecated delete() method was removed (since it was moved to show / entity list in 8.x)

New way to configure Sharp, via a dedicated builder class

The config/sharp.php file was entirely removed in favor of a dedicated builder class. This is not a breaking change since the config file is still supported, but deprecated, so you are encouraged to migrate to the new builder class.

To migrate, you should first create a new Service Provider which extends Code16\Sharp\SharpAppServiceProvider and implements the configureSharp() method:

php
use Code16\Sharp\SharpAppServiceProvider;

class MySharpServiceProvider extends SharpAppServiceProvider
{
    protected function configureSharp(SharpConfigBuilder $config): void
    {
        $config
            ->setName('My project')
            ->addEntity('posts', PostEntity::class)
            // ...
    }
}

Report all you configuration using the API of this new SharpConfigBuilder class. It should be pretty straightforward, as all the methods are named after the config keys they replace. For example:

In 8.x:

php
// Old config/sharp.php
return [
    'name' => 'Demo project',
    'custom_url_segment' => 'sharp',
    'display_breadcrumb' => true,
    'entities' => [
        'posts' => \App\Sharp\Entities\PostEntity::class,
    ],

    'global_filters' => fn () => auth()->id() === 1 ? [] : [\App\Sharp\DummyGlobalFilter::class],

    'search' => [
        'enabled' => true,
        'placeholder' => 'Search for posts or authors...',
        'engine' => \App\Sharp\AppSearchEngine::class,
    ],

    'menu' => \App\Sharp\SharpMenu::class,

    // ...
];

In 9.x:

php
class MySharpServiceProvider extends SharpAppServiceProvider
{
    protected function configureSharp(SharpConfigBuilder $config): void
    {
        $config
            ->setName('Demo project')
            ->setCustomUrlSegment('sharp')
            ->setDisplayBreadcrumb()
            ->addEntity('posts', PostEntity::class)
            ->addGlobalFilter(DummyGlobalFilter::class) // The auth()->id() === 1 no longer can be handled here, as the auth context is yet not available. Use the new authorize() method of the global filter instead.
            ->enableGlobalSearch(AppSearchEngine::class, 'Search for posts or authors...')
            ->setMenu(SharpMenu::class)
            // ...
    }
}

WARNING

Be sure to register this new Service Provider in your app.

New middleware to declare

Due to migration to inertia, two middleware must be added to the config.

INFO

if you migrated to the new config builder class, you should be ok unless you have explicitly overridden the whole middleware list.

Here is the impact on the deprecated config file:

php
// config/sharp.php

return [
    'middleware' => [
        // ...
        'web' => [
            // ...
            \Code16\Sharp\Http\Middleware\HandleSharpErrors::class,
            \Code16\Sharp\Http\Middleware\HandleInertiaRequests::class,
        ],
    ],
]

Migration to blade-icons

In 8.x, menu icons was FontAwesome classes like fa fa-user or fas fa-user. Now icons must be blade-icons icon names with its associated package installed.

Icons are not required but if you want to keep FontAwesome, you can install the following package:

bash
composer require owenvoke/blade-fontawesome

And rename old icon names to blade-fontawesome names in your SharpMenu :

diff
# Solid icons
- ->addEntityLink('entity', 'Entity', 'fas fa-user')
- ->addEntityLink('entity', 'Entity', 'fa fa-user')
+ ->addEntityLink('entity', 'Entity', logo: 'fas-user')

# Regular (outline) icons
- ->addEntityLink('entity', 'Entity', 'far fa-envelope')
- ->addEntityLink('entity', 'Entity', 'fa fa-envelope-o')
+ ->addEntityLink('entity', 'Entity', logo: 'far-envelope')

# Brand icons
- ->addEntityLink('entity', 'Entity', 'fa fa-github')
- ->addEntityLink('entity', 'Entity', 'fab fa-github')
+ ->addEntityLink('entity', 'Entity', logo: 'fab-github')

If you were using old fontawesome 4 icons you may need to rename them.

No more Bootstrap.css / Font awesome classes

You may be using Custom HTML (entity list row, editor embeds, form HTML field, form Autocomplete item template, page alerts) with CSS classes that was present in Sharp 8.x but that don't exist anymore:

  • If you were using bootstrap classes like row / col / badge in HTML content. These are no longer available, you can either :
    • Convert to inline CSS (for bootstrap grid classes / utilities)
    • Inject a custom CSS file as described here
  • If you were using inline Font Awesome icons like <i class="fas fa-user">
    • Using blade-fontawesome component like : <x-fas-user style="width: 1rem; height: 1rem" />. In Sharp 9.x all templates are now Blade.
    • For <i class="fas fa-user"> inside a custom transformer of an EntityList field, you must now do Blade::render('<x-fas-user style="width: 1rem; height: 1rem" />')

Page Alerts (aka global messages) are not based on Vue templates anymore

This part has been entirely rewritten, and will need substantial changes in your code.

In 8.x and below, you were asked to configure page alerts in the buildConfig() method; and if your page alert was displaying dynamic data, you had to use a custom transformer to inject the data in the page alert. All of this was removed, in favor of a much simpler "back only" system. Here’s an example of a page alert in a Show Page (this is the same in Form, Dashboard, Entity List, Embed and Command cases):

php
class MyShow extends SharpShow
{
    // ...
    
    protected function buildPageAlert(PageAlert $pageAlert): void
    {
        $pageAlert
            ->setLevelInfo()
            ->setMessage(function (array $data) {
                return $data['is_planned']
                    ? 'This post is planned for publication, on ' . $data['published_at']
                    : null;
            });
    }
}

As you can see, this new buildPageAlert() method takes a PageAlert object as parameter to work with. You'll have access to the $data array returned by your find() or getListData() method, to inject dynamic data in your page alert if needed. Vue templates are no longer handled, as the page alert is now rendered on the back only.

See global page alert documentation for more detail.

This bug fix potentially brings a breaking change: if you were using a custom transformer to handle related models, you may have to update it.

Here’s code which will work in Sharp 8.x and below:

php
$this
    ->setCustomTransformer('customer:name', function ($value, $instance, $attribute) { 
        return $instance->customer->name; // $instance is the Order
    })
    ->transform(Order::find(1))

Is has to be rewritten like this in Sharp 9.x:

php
$this
    ->setCustomTransformer('customer:name', function ($value, $instance, $attribute) { 
        return $instance->name; // $instance is the Customer, as it should be.
    })
    ->transform(Order::find(1))

The main difference is that the $instance parameter refers to the related model, not the main model anymore. To summarize:

In 8.x:

php
$value: 'Joe Doe'
$instance: // the Order instance
$attribute: 'customer:name'

In 9.x:

php
$value: 'Joe Doe'
$instance: // the **Customer** instance
$attribute: 'name'

Thumbnails custom filters must be refactored to Modifiers

First, if you defined custom filters classes for your thumbnails, you must refactor it to the new ThumbnailModifier API, which is very close:

In 8.x

php
class MyFilter extends ThumbnailFilter
{
    public function applyFilter(Image $image): Image
    {
        // ...
    }
}

In 9.x

php
use Code16\Sharp\Form\Eloquent\Uploads\Thumbnails\ThumbnailModifier;
use Intervention\Image\Interfaces\ImageInterface;

class MyModifier extends ThumbnailModifier
{
    public function apply(ImageInterface $image): ImageInterface
    {
        // ...
    }
}

And secondly, in 9.x you can’t pass modifier's parameters as an array anymore:

In 8.x

php
$book->cover->thumbnail(100, 100, ['fit'=>['w'=>100, 'h'=>100]]);

In 9.x

php
$book->cover->thumbnail(100, 100, [new FitModifier(100, 100)]);

// or with the new fluent API
$book->cover->thumbnail()
    ->addModifier(new FitModifier(100, 100))
    ->make();

currentSharpRequest() is now deprecated in favor of sharp()-⁠>context() helper

The currentSharpRequest() helper is now deprecated, and will be entirely removed in a future version. You should migrate your code to use the sharp()-⁠>context() helper instead (see the dedicated documentation).

SharpAuthenticationCheckHandler is now deprecated in favor of viewSharp Gate

The use of a SharpAuthenticationCheckHandler is now deprecated, and will be entirely removed in a future version. You should migrate your handler to a Gate:

In 8.x:

php
class MySharpAuthenticationCheckHandler implements SharpAuthenticationCheckHandler
{
    public function check(Authenticatable $user): bool;
    {
        return $user->is_sharp_admin;
    }
}

In 9.x:

php
class AppServiceProvider extends ServiceProvider
{
    // ...

    public function boot(): void
    {
        Gate::define('viewSharp', fn ($user) => $user->is_sharp_admin);
    }
}

TIP

You should place this code in the new Sharp dedicated Service Provider you will create to configure your Sharp app, overriding the declareAccessGate() method. See the dedicated documentation.

Next, the sharp.auth.check_handler config key can be safely removed from your config/sharp.php file (in case you have not yet migrated to the dedicated builder class, see above), along with the SharpAuthenticationCheckHandler implementation class.

Injected CSS must now be loaded with the SharpConfigBuilder

In 8.x,

php
// config/sharp.php

return [
    'extensions' => [
       'assets' => [
          'strategy' => 'vite',
          'head' => [
             'resources/css/sharp.css',
          ],
       ],
    ],
];

In 9.x :

php
class MySharpServiceProvider extends SharpAppServiceProvider
{
    protected function configureSharp(SharpConfigBuilder $config): void
    {
        $config
            ->loadViteAssets(['resources/css/sharp.css']) // to load a CSS file built with Vite
            ->loadStaticCss(asset('/css/sharp.css')) // Or to load a static CSS file
    }
}

All test assertions were removed

All assertions, like for instance assertSharpHasAuthorization, were removed because they were clumsy and not really useful. You must remove them from your tests, and use standard comparisons instead — although in real world, it’s easier and cleaner to just check the return status (ie: assertOk()) and check, if needed, the consequences in the database directly.

This means you also need to remove all $this-⁠>initSharpAssertions() calls from your tests.

Of course, the test helpers remain available, see the dedicated testing documentation.

Dashboard

SharpWidgetPanels are now based on blade template

In a similar way to Page Alerts, we abandoned Vue templates for custom SharpWidgetPanels in favor of blade templates. This is a breaking change, as the setTemplatePath(...)and setInlineTemplate(...) methods were removed, placed by a unique setTemplate(View $template).

There's almost nothing to change on the PHP side:

In 8.x:

php
class MyDashboard extends SharpDashboard
{
    // ...
    
    protected function buildWidgets(WidgetsContainer $widgetsContainer): void
    {
        $widgetsContainer
            ->addWidget(
                SharpPanelWidget::make('my_custom_panel')
                    ->setTitle('My custom panel')
                    ->setTemplatePath('sharp.templates.my_template') // Must be an existing **vue file** 
            );
    }
}

In 9.x:

php
class MyDashboard extends SharpDashboard
{
    // ...
    
    protected function buildWidgets(WidgetsContainer $widgetsContainer): void
    {
        $widgetsContainer
            ->addWidget(
                SharpPanelWidget::make('my_custom_panel')
                    ->setTitle('My custom panel')
                    ->setTemplate(view('sharp.templates.my_template')) // Must be an existing **blade view**
            );
    }
}

The main change is the template itself, which must be a blade view now.

See panel widget documentation for more detail.

Entity Lists

Entity Lists have a new authorization: reorder

Previously the reorder authorization was handled by the update authorization, which can lead to unwanted effects. You should now declare a specific reorder authorization in your Policies:

php
class PostPolicy extends SharpEntityPolicy
{
    public function reorder($user): bool
    {
        return $user->isEditor();
    }
    
    // ...
}

Entity List's setWidth() method as a new signature (non-breaking change: old signature is still supported)

The -⁠>setWith($width) method now expects a percentage value, expressed as a string (eg: '20' or '20%'), a float (eg: .2 for 20%) or an integer (eg: 20 for 20%). The old signature use to accept a 1 to 12 integer (12-grid): it is still supported (Sharp will transform a 6 in 50%), but deprecated, and you are strongly encourage to migrate to the new signature.

Methods to handle Entity List columns width on small screen were deprecated

The -⁠>setWithOnSmallScreen($width) and -⁠>setWithOnSmallScreenFill() methods were deprecated, because they are no more used in the new front table UI system. You can safely remove them, Sharp will rely on the setWidth($width) method, or, even easier, will deduce width based on content like a regular table.

The -⁠>hideOnSmallScreens() method remains.

All filters must be declared in order to be used

In Sharp 8.x it was possible, in an Embedded Entity List (EEL) case, to use a filter without declaring it. This was a kind of bug, and has been fixed in 9.x: all filters must be declared in the getFilters() method.

Consider this code in 8.x, where we have a PostShow that embeds a PostBlockList as an EEL:

php
class PostShow extends SharpShow
{
    protected function buildShowFields(FieldsContainer $showFields): void
    {
        $showFields
            ->addField(SharpShowTextField::make('title')->setLabel('Title'))
            ->addField(
                SharpShowEntityListField::make('blocks')
                    ->setLabel('Blocks')
                    ->hideFilterWithValue('post', fn($instanceId) => $instanceId)
            );
    }
    // ...
}

class PostBlockList extends SharpEntityList
{
    // ...

    protected function getFilters(): ?array
    {
        return [
            // Nothing there
        ];
    }

    public function getListData(): array|Arrayable
    {
        return $this->transform(
            PostBlock::query()
                ->where('post_id', $this->queryParams->filterFor('post'))
                ->get()
        );
    }
}

We can see that PostBlockList does not define any Filter, but uses one in the getListData() method, valued by the PostShow via hideFilterWithValue(). In 9.x, this won't work as the Filter must be declared in the getFilters() method. There is a new way to quickly declare such Filters that are not meant to be shown to the user, HiddenFiler:

In 9.x

php
use \Code16\Sharp\EntityList\Filters\HiddenFilter;

class PostBlockList extends SharpEntityList
{
    // ...

    protected function getFilters(): ?array
    {
        return [
            HiddenFilter::make('post')
        ];
    }
    
    // ... The rest is the same
}

You can of course instead declare a real Filter.

Select filter configureTemplate() has been dropped

If you were using this method, you must do the string transformation in the label of each value.

New performance optimization for Commands and Policies in Entity List (n+1)

This is not a breaking change, in fact you can ignore this step entirely, but since it's can lead to a significative performance boost, this is worth mentioning: you can now quite easily implement a caching mechanism of instances for your Commands and Policies in Entity List.

Forms & Shows

Form and Show layout methods were renamed (old ones are deprecated)

The -⁠>withSingleField() method was deprecated, in favor of:

  • -⁠>withField(string $fieldKey) for simple fields
  • -⁠>withListField(string $fieldKey, Closure $subLayoutCallback) for List fields, which requires a sub-layout handled by a callback.

The method -⁠>withFields(string ...$fieldKeys), used for multiple fields layout, remains unchanged.

Form and Show Fields are now formatted even if you don’t transform them

This shouldn’t cause any trouble, as this is a fix, but it could break unorthodox code: field formatters (which are used to format the field value for the frontend) are now properly and always called before displaying data to the front, even if you don’t transform your data with $this-⁠>transform() method.

Forms

New validation system (and deprecation of the old one)

The validation system was odd, for legacy reasons. In 9.x, it has been rewritten to be in phase with Laravel and to be more consistent:

  • validation rules can now be defined in a rules() method of the form / command class,
  • or with a -⁠>validate($data, $rules) call before update / store.
  • The $formValidatorClass property usage, in a SharpForm, is now deprecated (you are strongly encouraged to migrate to the rules() method instead).

This code in 8.x:

php
class PostForm extends SharpForm
{
    protected ?string $formValidatorClass = PostFormValidator::class;

    // ...
}

class PostFormValidator extends SharpFormRequest
{
    public function rules(): array
    {
        return [
            'title' => 'required',
            'content' => 'required',
        ];
    }
}

Should be rewritten in this in 9.x:

php
class PostForm extends SharpForm
{
    public function rules(): array
    {
        return [
            'title' => 'required',
            'content' => 'required',
        ];
    }

    // ...
}

Or:

php
class PostForm extends SharpForm
{
    // ...

    public function update($id, array $data)
    {
        $this->validate($data, [
            'title' => 'required',
            'content' => 'required',
        ]);

        // ...
    }
}

This version brings two huge benefits (besides the fact that it's clearer):

  • the "delayed creation" thing is gone (hooray!): the {id} parameter in a SharpFormUploadField storageBasePath isn't anymore an issue in creation case as Sharp will no longer call the update() method twice.
  • Validation is now called AFTER data formatters, even in SharpForm (it was already the case with Command).

Breaking changes: the 8.x and below validation is still allowed, but deprecated.

If you decide to migrate (and you should), pay attention to:

  • remove special workarounds you may have done to handle the "delayed creation" thing,
  • remove the .text suffix you may have added for SharpFormEditorField validation rules.

If you decide not to migrate just now, you should ensure that the \Code16\Sharp\Http\Middleware\Api\BindSharpValidationResolver middleware in added to the api group:

either in the (deprecated) config file:

php
// config/sharp.php

return [
    'middleware' => [
        //...
        'api' => [
            // ...
            \Code16\Sharp\Http\Middleware\Api\BindSharpValidationResolver::class,
        ],
    ],
]

... or in the shinny new config builder:

php
class MySharpServiceProvider extends SharpAppServiceProvider
{
    protected function configureSharp(SharpConfigBuilder $config): void
    {
        $config
            ->appendToMiddlewareApiGroup(
                \Code16\Sharp\Http\Middleware\Api\BindSharpValidationResolver::class
            )
            // ...
    }
}

Localization feature was removed for SharpFormSelectField, SharpFormTagsField and SharpFormAutocompleteField fields

Those fields could be localized in 8.x in a weird way: labels were localized, but not values. This was really misleading, so we decided to remove entirely this behavior in 9.x. The only real impact should be to remove setLocalized() calls in your code for these fields.

SharpFormGeolocationField using Google Maps API must now provide a Map ID

Sharp 9.x now uses Advanced Markers which requires a Map ID, register it with the following method of the field :

php
class PostForm extends SharpForm
{
    public function buildFormFields(FieldsContainer $formFields): void
    {
        $formFields->addField(
            SharpFormGeolocationField::make('position')
                ->setMapsProvider('gmaps')
                ->setApiKey('...')
                ->setGoogleMapsMapId('...') // new method
        );
    }
}

SharpFormAutocompleteFormField was rewritten and need to be migrated

First, the SharpFormAutocompleteFormField class was split into two classes: SharpFormAutocompleteLocalField and SharpFormAutocompleteRemoteField, to clearly separate these two different use cases.

Second, Vue templates must be migrated to Blade templates (similar to the SharpWidgetPanel or Page Alerts migrations). You can either pass a view name or a blade template directly to the newly named setListItemTemplate() and setResultItemTemplate() methods (the old setListItemInlineTemplate(), setListItemTemplatePath(), setResultItemInlineTemplate() and setResultItemTemplatePath() were removed).

The setAdditionalTemplateData() method was also removed, in favor of a more straightforward way to pass additional data to the template.

Example in 8.x:

php
class PostForm extends SharpForm
{
    public function buildFormFields(FieldsContainer $formFields): void
    {
        $formFields
            ->addField(
                SharpFormAutocompleteField::make('author_id', 'remote')
                    ->setRemoteEndpoint('/api/admin/users')
                    ->setListItemInlineTemplate('{{name}}')
                    ->setResultItemInlineTemplate('{{name}}')
            )
            ->addField(
                SharpFormAutocompleteField::make('category_id', 'local')
                    ->setLocalValues([
                        1 => 'Category 1',
                        2 => 'Category 2',
                        3 => 'Category 3',
                    ])
            )
            ->addField(
                // ...
            );
    }
    
    // ...
}

In 9.x:

php
class PostForm extends SharpForm
{
    public function buildFormFields(FieldsContainer $formFields): void
    {
        $formFields
            ->addField(
                SharpFormAutocompleteRemoteField::make('author_id')
                    ->setRemoteEndpoint('/api/admin/users')
                    ->setListItemTemplate('{{$name}}')
            )
            ->addField(
                SharpFormAutocompleteLocalField::make('category_id')
                    ->setLocalValues([
                        1 => 'Category 1',
                        2 => 'Category 2',
                        3 => 'Category 3',
                    ])
            )
            ->addField(
                // ...
            );
    }
    
    // ...
}

Finally, there is a big evolution which concerns the remote autocomplete endpoint: your 8.x implementation should still work, but you should note that:

  • you can now directly write the autocomplete endpoint as a callback closure in the field (no need to use a dedicated route + controller),
  • external endpoint URLs aren’t supported anymore (you must write a wrapper around this external endpoint, either as a route + controller or via the new callback option).

Example in 8.x:

php
class PostForm extends SharpForm
{
    public function buildFormFields(FieldsContainer $formFields): void
    {
        $formFields
            ->addField(
                SharpFormAutocompleteField::make('author_id', 'remote')
                    ->setRemoteEndpoint('/api/admin/users')
                    ->setListItemInlineTemplate('{{name}}')
                    ->setResultItemInlineTemplate('{{name}}')
            );
    }
    
    // ...
}

In 9.x:

php
class PostForm extends SharpForm
{
    public function buildFormFields(FieldsContainer $formFields): void
    {
        $formFields
            ->addField(
                SharpFormAutocompleteRemoteField::make('author_id')
                    ->setRemoteCallback(function ($search) {
                        return User::where('name', 'like', "%$search%")->get();
                    })
                    ->setListItemTemplate('{{$name}}')
            );
    }
    
    // ...
}

This isn't a breaking change, since the old methods are still available, but deprecated. You should migrate to the new methods:

  • setFileFilterImage() -> setImageOnly()
  • setCropRatio() = setImageCropRatio()
  • shouldOptimizeImage() = setImageOptimize()
  • setTransformable() = setImageTransformable()
  • setCompactThumbnail() = setImageCompactThumbnail()

and in addition:

  • setFilterFilter() -> setAllowedExtensions()

See full documentation here.

The API for embedded uploads in Editor field was rewritten

The SharpFormEditorField no longer has all the upload-related methods directly in the class. Instead, you must use a new SharpFormEditorUpload builder class, passed as a parameter to the allowUploads() method.

In 8.x:

php
// in a SharpForm
public function buildFormFields(FieldsContainer $formFields): void
{
    $formFields->addField(
        SharpFormEditorField::make('content')
            ->setMaxLength(1000)
            ->setToolbar([
                SharpFormEditorField::B,
                SharpFormEditorField::A,
                SharpFormEditorField::UPLOAD,
            ])
            ->setStorageDisk('local')
            ->setStorageBasePath('data/posts/{id}/embed'),
        )
    );
}

In 9.x:

php
// in a SharpForm
public function buildFormFields(FieldsContainer $formFields): void
{
    $formFields->addField(
        SharpFormEditorField::make('content')
            ->setMaxLength(1000)
            ->setToolbar([
                SharpFormEditorField::B,
                SharpFormEditorField::A,
                SharpFormEditorField::UPLOAD,
            ])
            ->allowUploads(
                SharpFormEditorUpload::make()
                    ->setStorageDisk('local')
                    ->setStorageBasePath('data/posts/{id}/embed')
            );
    );
}

See full documentation here.

New markup for Embedded uploads (in Editor field)

If you are using SharpFormEditorField uploads, you will need migrate <x-sharp-image> and <x-sharp-file> elements in the content, meaning in the database. Sharp provides a helper trait intended to be used in your migration like this:

php
use Code16\Sharp\Form\Eloquent\Migrations\MigrateEditorContentsForSharp9;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;

new class extends Migration
{
    use MigrateEditorContentsForSharp9;

    public function up(): void
    {
        $this->updateEditorContentOf(DB::table('posts'), ['content']);
    }
}

Editor embeds has now blade templates

Like Autocomplete / Dashboard Widget panel, Editor embeds must now be blade inline string or a view('...') :

Inline templates

Inline templates in 8.x :

php
public function buildEmbedConfig(): void
{
    $this
        ->configureFormInlineTemplate('<div v-if="online">{{ title }}</div>')
        ->configureShowInlineTemplate('<div v-if="online">{{ title }}</div>');
}

Inline templates in 9.x :

php
public function buildEmbedConfig(): void
{
    $this
        // if only one template is defined (for both form & show)
        ->configureTemplate('@if($online) <div>{{ $title }}</div> @endif')
        
        // if form & show has 2 different templates
        ->configureFormTemplate('@if($online) <div>{{ $title }}</div> @endif')
        ->configureShowTemplate('@if($online) <div>{{ $title }}</div> @endif');
}

Path templates

Path templates in 8.x :

php
public function buildEmbedConfig(): void
{
    $this
        ->configureFormTemplatePath('sharp/embed.vue')
        ->configureShowTemplatePath('sharp/embed.vue');
}

Path templates in 9.x :

php
public function buildEmbedConfig(): void
{
    $this
        // if only one template is defined (for both form & show)
        ->configureTemplate(view('sharp.embed'))
        
        // if form & show has 2 different templates
        ->configureFormTemplate(view('sharp.embed'))
        ->configureShowTemplate(view('sharp.embed'));
}

SharpFormListField collapsed items template feature was removed

setCollapsedItemInlineTemplate() & setCollapsedItemTemplatePath() methods was removed due to limited usage and general migration into blade templates.

SharpFormHtmlField has migrated to blade templates

setInlineTemplate() & setTemplatePath() must be converted to :

  • setTemplate('blade template string') or
  • setTemplate(view('sharp.form-field')).

See field page for more information.

Released under the MIT License.