PHPackages                             monstrex/voyager-site - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Admin Panels](/categories/admin)
4. /
5. monstrex/voyager-site

ActiveLibrary[Admin Panels](/categories/admin)

monstrex/voyager-site
=====================

Voyager Site package

v1.0.4(5mo ago)161.6k9[4 PRs](https://github.com/MonstreX/voyager-site/pulls)MITPHPCI failing

Since Apr 17Pushed 2mo ago4 watchersCompare

[ Source](https://github.com/MonstreX/voyager-site)[ Packagist](https://packagist.org/packages/monstrex/voyager-site)[ Docs](https://github.com/monstrex/voyager-site)[ RSS](/packages/monstrex-voyager-site/feed)WikiDiscussions master Synced today

READMEChangelog (10)Dependencies (5)Versions (31)Used By (0)

Voyager Site
============

[](#voyager-site)

> Important: this is a new major release of `voyager-site` with breaking changes. The package has been redesigned to align with the current Voyager fork and updated media stack. If you need the legacy implementation, use the archived release instead.

[![Latest Version on Packagist](https://camo.githubusercontent.com/1219efebf429be0fdfe56f652910809562b0a8b88809b3d3443e88634648f4fe/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d6f6e73747265782f766f79616765722d736974652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/monstrex/voyager-site)[![Total Downloads](https://camo.githubusercontent.com/a2aeb9a2db64469491763da62d3ed64c3bb1df25c1eafa45c4d0f118f7b20dd9/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d6f6e73747265782f766f79616765722d736974652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/monstrex/voyager-site)[![Build Status](https://camo.githubusercontent.com/7baa9588d21a75b2ce9a1a498c79a8038e3b5db652b319e9f532cb797879a8b6/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f6d6f6e73747265782f766f79616765722d736974652f6d61737465722e7376673f7374796c653d666c61742d737175617265)](https://travis-ci.org/monstrex/voyager-site)

The package is an implementation of a simple but useful subsystem of a basic content organization for the [Voyager Admin Panel](https://github.com/monstrex/voyager) package. Using this package you can rapidly and easily build small and medium-size scale websites.

Features
--------

[](#features)

- Basic Page management module, including systems pages.
- SEO with basic meta, optional Open Graph/Twitter tags, and canonical URL.
- Breadcrumbs implementation.
- Flexible Block / Widget management module, to build parts of your site pages.
- Form management system, including AJAX sending.
- [Liquid template](https://packagist.org/packages/liquid/liquid) subsystem for blocks/widgets and forms.
- [Shortcodes](https://github.com/webwizo/laravel-shortcodes) integrated.
- Localizations from DB table, where you can easily keep and manage your translations.
- Advanced site settings module, including mail smtp settings and a mail sending test out of the box.
- Sitemap generator (configurable, disabled by default).
- Scripts manager (inject code blocks into head/body positions).

Installation
------------

[](#installation)

> #### Requirement
>
> [](#requirement)
>
> You should install the package [Voyager](https://github.com/monstrex/voyager) before.

Via Composer

```
$ composer require monstrex/voyager-site
```

Then run install command:

```
$ php artisan voyager-site:install
```

Install options:

```
--force        Force operations in production
--refresh      Refresh Voyager Site seed data only (no migrations)
--locale=xx    Locale to use while refreshing seed data

```

Refresh seed data:

```
php artisan voyager-site:install --refresh
php artisan voyager-site:install --refresh --locale=ru
```

Publish config if you need:

```
$ php artisan vendor:publish --provider="MonstreX\VoyagerSite\VoyagerSiteServiceProvider" --tag="config"

```

Publish assets if you build them locally:

```
$ php artisan vendor:publish --provider="MonstreX\VoyagerSite\VoyagerSiteServiceProvider" --tag="assets" --force

```

To uninstall:

```
$ php artisan voyager-site:uninstall

```

### Asset build (Vite)

[](#asset-build-vite)

```
$ npm install
$ npm run build

```

Built assets are located in `publishable/assets` and are published to `public/vendor/voyager-site`.

Usage
-----

[](#usage)

### Config file

[](#config-file)

- **route\_home\_page** - Route name for Home Page ('home' by default).
- **default\_model\_table** - Default model table name to find records ('pages' by default).
- **default\_slug\_field** - Default slug field name ('slug' by default).
- **use\_legacy\_error\_handler** - If *false* the voyager-site 404 error handler is used.
- **template** - Root folder name where stored view template files ('template' by default).
- **template\_master** - Master template name ('layouts.master' by default).
- **template\_layout** - Main Layout Template name ('layouts.main' by default).
- **template\_page** - Page template name ('pages.page' by default).
- **template\_filters** - Class to add custom Liquid filters or Null.

### Site Settings

[](#site-settings)

Site settings is a flexible and extendable easy to use settings subsystem integrated in the package.

[![Site settings](/docs/images/settings-1.png)](/docs/images/settings-1.png)

You can use and modify exist settings and group and add you own group and settings. To retrieve certain setting you may use helper function:

```
$mail = site_setting('mail.to_address');
```

> Some of the site settings used by the internal package functions will override Laravel .env settings.

The settings have built-in SMTP mail parameters and the mail sending test function. [![Site settings - Mail](/docs/images/settings-mail.png)](/docs/images/settings-mail.png)SEO settings include the base meta fields and optional Open Graph/Twitter/common fields with feature toggles.

You can easily modify settings or add new ones using JSON-like setting fields configuration by clicking on the Edit action.

```
{
    "fields": {
        "to_address": {
            "label": "Default address for site emails",
            "type": "text",
            "value": "destination@example.com",
            "class": "col-md-12"
        },
        "section_smtp": {
            "type": "section",
            "icon": "voyager-mail",
            "label": "E-Mail transport"
        },
        "driver": {
            "label": "Mail driver",
            "type": "dropdown",
            "value": "smtp",
            "options": {
                "smtp": "SMTP",
                "mailgun": "MAILGUN",
                "log": "LOG"
            },
            "class": "col-md-12"
        }
    }
}
```

Built-in field types are

- text
- number
- textarea
- rich\_text\_box (Jodit editor)
- code\_editor (Ace editor)
- checkbox
- radio
- image (voyager type image)
- media (image file, using Voyager media storage)
- route (returns URL using route name)
- section (don't has value, used just for visual separation of field groups)

### Localizations

[](#localizations)

The package provides DB-like localization storage for all strings you need to localize. Just add language columns to the storage and it'll be used instead a localization in files.

[![Localizations](/docs/images/localizations.png)](/docs/images/localizations.png)

Example:

```
str_trans('[[en]]Hello[[ru]]Privet');
```

### Pages

[](#pages)

The VPage module allows you manage basic pages on your site. You can easily find and prepare any page and its related attributes - like SEO data, breadcrumbs and data sources and then send this data collection to a view. It can be used by two ways: implementing the **PageTrait** class into your controller or using the facade **VPage**. Look for the examples:

Example #1:

```
namespace App\Http\Controllers;

use MonstreX\VoyagerSite\Traits\PageTrait;

class PagesController extends Controller
{
    use PageTrait;

    public function home()
    {

        $this->create('home');

        return $this->view();

    }

    public function show($alias)
    {

        $this->create($alias);

        return $this->view();

    }

    public function showArticle($alias)
    {

        $this->create($alias,'articles');

        return $this->view('layout.article', ['vars' => $some_vars]);

    }
}
```

Example #2:

```
namespace App\Http\Controllers;

use MonstreX\VoyagerSite\Traits\PageTrait;

use VSite, VPage, VData;

class PagesController extends Controller
{
    public function home()
    {

        VPage::create(VData::find('home'), VSite::getSettings());

        return VPage::view();

    }
}
```

What the example does:

- Finds in default (or given) model the certain record (using 'slug' field by default). If you use (int) value then it'll be found by ID field. If a record is not found or the record has empty (null) **status** field then it'll throw an exception 404.
- Creates a VPage instance and initialize the instance with a Page Data:
    - Founded model object.
    - Site settings.
    - Initialized breadcrumbs.
    - Initialized SEO parameters (seo title, meta description, meta keywords).
    - Attached data sources, if **details** field has data sources descriptions.
- Renders page using default (or given) View.

Available variables in the View:

```
$template            // Root template folder
$template_master     // Master template name (to extend View)
$template_page       // Internal page template name
$breadcrumbs         // Breadcrumbs array
$title               // Page title
$banner              // Page banner image (if present)
$page                // Page instance
$parents             // Chain of parents of current page
$children            // Children pages if present for current page
$data_sources        // Extra Data sources attached to the Page
$seo['title']        // Seo Title
$seo['description']  // Meta Description
$seo['keywords']     // Meta Keywords
$data                // Additional given data
```

### Page Data Sets

[](#page-data-sets)

It is a subsystem to retrieve additional data necessary to use on a certain page. The data are different record collections from different models.
To use it you need having **details** field in your model, the record of that filled up with a certain JSON data structure:

> Note: the attached data defined in JSON structure will load automatically during a call the **create** method.

```
{
    "data_sources": {
        "articles": {
            "model": "Article",
            "where": {
              "status": 1
            }
        },
        "services": {
            "model": "Service",
            "where": {
                "status": 1,
                "featured": 0,
                "type": "main"
            },
            "with": [
              "category",
              "country"
            ],
            "order" : {
                "field" : "order",
                "direction" : "asc"
            }
        }
    }
}
```

And in your View template you can easily use it like this:

```
@foreach($data_sources['articles'] as $article)
    {{ $article['title'] }}
@endforeach
```

> Note: this type of the JSON data structure also uses in Block/Widget subsystems.

### Override default templates on the page

[](#override-default-templates-on-the-page)

You may want to override default template names on a certain page. To do this define new template names in **details** field:

```
{
  "template": "my-theme",
  "template_master": "layout.master",
  "template_layout": "layout.main",
  "template_page": "pages.contacts"
}
```

Overriding in controllers (using page trait):

```
public function service($alias)
{
    $pageContent = $this->create($alias,'services')->getContent();
    $this->setPageTemplate('pages.service');
    $this->buildBreadcrumbs();
    $this->setChildren('parent_id');
    return $this->view();
}
```

### Page SEO parameters

[](#page-seo-parameters)

SEO parameters are generated inside the **create** Page method. By default:

**SEO Title** - from the page seo fields group if an appropriate field is not empty, otherwise checks field **Title**, if the field is not present then checks a site setting **seo.seo\_title**, if the setting is empty then takes value from site setting **general.site\_title**. And at last the given value passed through seo title template site setting - **seo.seo\_title\_template**.

> You can override the **SEO Title** value with method **VPage::setSeoTitle('new title')**.

**META Description** - from the page seo fields group if an appropriate field is not empty, otherwise checks a site setting **seo.meta\_description**, if the setting is empty then takes value from site setting **general.site\_description**.

> You can override the **META Description** value with method **VPage::setMetaDescription('new description')**.

**META Keywords** - from the page seo fields group if an appropriate field is not empty, otherwise checks a site setting **seo.meta\_keywords**.

> You can override the **META Keywords** value with method **VPage::setMetaKeywords('new keywords')**.

### Open Graph, Twitter, Canonical

[](#open-graph-twitter-canonical)

Open Graph, Twitter, and Canonical tags are rendered by the `seo_tags()` helper and are **disabled by default**.
Enable them in **Site Settings -&gt; SEO**:

- **Enable canonical URL tag**
- **Enable Open Graph tags**
- **Enable Twitter Card tags**

Auto-generated values:

- **Canonical URL** defaults to the current URL (or model URL if provided).
- **OG/Twitter title** uses the resolved SEO title.
- **OG/Twitter description** uses the resolved meta description.

Global fields (Site Settings -&gt; SEO) provide shared defaults (site name, type, images, card type, etc).
Per-page overrides for OG/Twitter can be provided via `seo_meta()` input (model `seoMeta()` or array), but page fields are **not** extended by default.

### Page Breadcrumbs

[](#page-breadcrumbs)

When you call the Page **create** method it adds the first element to the **Breadcrumbs** array.

How sets the first breadcrumb element:

```
addBreadcrumbs(__('site.breadcrumb_home'), route(config('voyager-site.route_home_page')));
```

To add other elements to the **Breadcrumbs** array just use the method **VPage::addBreadcrumbs($title, $path)**

Also you can use the method **buildBreadcrumbs()** to build a chain of nested pages which hold in the Parents property. This property sets automatically when you load and create page instance using the method **setParents($page, $parent\_field\_name)**Where $page is a current page instance and $parent\_field\_name is a field name where holds ID with a parent of the current page.

> Note: additional necessary setup for models - to build **parents chain**, **breadcrumbs** and get **banner**

```
// Example (Additional Model properties)
public $masterPageRouteName = 'page';
public $masterPageSlug = 'pages';
public $masterPageId = 2;
public $pageRouteName = 'service';
public $bannerField = 'banner_image';
```

### Blocks / Widgets

[](#blocks--widgets)

Blocks / Widgets is a flexible subsystem provides your a way to implement and organize additional content parts and include them into your page.
Each block has the follow structure:

**Status** - If disabled the block will be ignored.

**Title** - Visible only in admin panel.

**Block key** - A key (slug) using to find and render this block.

**Region position** - Used for grouping blocks and then render them as a group in certain order. Available positions can be edited in the **Regions** menu.

**Block content** - Main block content. You can use as pure HTML code or as a [Liquid template](https://packagist.org/packages/liquid/liquid).

Available variables:

- **this.images** - holds images items listed bellow.
- **this.field\_name** - holds additional fields values, where field\_name is additional field name in the block table.
- **data** - Data sources if defined in the **Options** field.

Example #1 (usage of image list):

```

My images

{% for image in this.images %}

{% endfor %}

```

Where **image.url** represent relative URL of image. **Crop** filter - crop and store (if not stored yet) the image with given sizes. -**url** filter - makes full url from the relative one. **image.full\_url** - Full url of the image. **image.props.**\* - Custom image properties.

Example #2 (usage data sources):

```

Articles Block

{% for article in data.articles %}
  {{ article.title }}
{% endfor %}

```

For this kind of template you need to define **data sources** JSON-like structure in the **options** field:

```
{
    "data_sources": {
        "articles": {
            "model": "Article",
            "where": {
                "status": 1,
                "news": 1
            },
            "order" : {
                "field" : "order",
                "direction" : "asc"
            }
        }
    }
}
```

Where "model" is a model name equal to registered model name in the Voyager Bread system.

Example #3 (usage internal block's fields):

```

{{ this.title }}
{{ this.images[0].url }}
{{ this.images[0].props.title }}
{{ this.additional_field }}
{{ options.data_section }}
```

Also you can get any field of the certain block using helper:

```
{{ get_block_field('top-line', 'title') }}
```

> Block render

Just use helper render\_block('key'). Instead of key you can use block Title or ID (numeric).

```
{!! render_block('top-line') !!}
{!! render_block('Our services') !!}
{!! render_block(3) !!}
```

> Region (group) render and URL path rules.

It can be used to organize and render a group of blocks whit the same region (group) name whenever you need it in your template. For instance:

```
{!! render_region('content-before') !!}
```

Will render all blocks where this region (group) 'content-before' has been set. And the package will check all blocks if they can be rendered - what depends on the setting "URL paths Rules":

[![URL path rules](/docs/images/regions-path-rules.png)](/docs/images/regions-path-rules.png)

It's a drupal-like block system rendering. That can depend on the current URL or not.

### Forms

[](#forms)

Similar to block. But you can use only limited sets of internal variables. The 'send.form' is implemented inside the form subsystem with the sendForm($request) method. It sends any form data including attached files. Also you can use Google ReCaptcha 2 form protection. Just add the line where you need inside your form:

```

```

And add recaptcha validation rules to the form options:

```
{
    "validator": {
        "g-recaptcha-response": "required|recaptcha"
    }
}
```

Template part:

```

    Send

```

Parameters part:

```
{
    "to_address": "info@site.com,support@site.com",
    "validator": {
        "name":"required",
        "email":"required",
        "phone":"required",
        "g-recaptcha-response": "required|recaptcha"
    },
    "messages": {
        "name.required": "The field NAME shouldn't be empty.",
        "email.required": "The field EMAIL shouldn't be empty.",
        "phone.required": "The field PHONE shouldn't be empty."
    }
}
```

If parameter 'to\_address' is not present will be used config setting: mail.to\_address.

Inside form template you can use internal vars:

```
{{ old }}
{{ errors_messages}}
{{ errors }}
{{ form_alias }}
{{ form_suffix }}
{{ form_subject }}}
{{ csrf_token }}
```

To render form from a view use helper renderForm($key, $subject = null, $suffix = null):

```
{!! render_form('callback-form', 'Send us a message!', '-second-form') !!}
```

To render inside a block:

```
{{ 'callback-form' | form: 'Send us a message!','-second-form' }}
```

More examples:

```

            Name

            {% if errors.name %}

                {% for error in errors.name %}
                  {{ error }}
                {% endfor %}

            {% endif %}

            Phone

            {% if errors.phone %}

                {% for error in errors.phone %}
                  {{ error }}
                {% endfor %}

            {% endif %}

            E-Mail address

            {% if errors.email %}

                {% for error in errors.email %}
                  {{ error }}
                {% endfor %}

            {% endif %}

            Message
            {{ old.message }}
            {% if errors.message %}

                {% for error in errors.message %}
                  {{ error }}
                {% endfor %}

            {% endif %}

            Attachment #1

        Submit

Form Messages
{% for message in errors_messages %}
  {{ message }}
{% endfor %}
```

Also you can use AJAX form sending. The package implements a small JS helper for AJAX sending (no jQuery required). Include this in your view (or use your own JS function):

```
@include('voyager-site::mail.send_form_ajax_js')
```

AJAX Example:

```

                Attachment

                    ...loading icon...
                    Send Form
                    Sending...

```

Built-in Shortcodes
-------------------

[](#built-in-shortcodes)

**block** - Render a block. Ex: \[block name="top-line"\]

**form** - Render a form. Ex: \[form name="top-line" subject="Form subject" suffix="-callback-form"\]

**div** - Render div wrapper. Nested elements not allowed. Ex: \[div class="wrapper"\] CONTENT \[/div\]

**image** - Render html code an image (and crop, convert an image) using media files attached to the current content instance.

Available options:
**field** - Media file field related with attached media files
**index** - Index of the file in the collection, begins with 1.
**url** - Path to the image (if not used field and index)
**class** - Classes for the image tag. Ex: class="lazy responsive"
**lightbox** - Make a lightbox wrapper. Ex: lightbox="true"
**lightbox\_class** - Classes for the lightbox wrapper
**width** - Width attribute fot the image tag.
**height** - Height attribute fot the image tag.
**picture** - Add picture wrapper.
**crop** - Crop the image.
**format** - Convert the image to webp, jpg, png.

Examples:
\[image field="image" index="1"\]
\[image url="/images/banners/banner-1.jpg"\]
\[image field="images" index="3" picture="true" format="webp" width="100" height="200" crop="400,400" class="lazy-class" lazy="true" lightbox\_class="image-gallery"\]

Built-in Liquid filters
-----------------------

[](#built-in-liquid-filters)

**url** - Return full url for a given path. Ex: {{ '/images/file.jpg' | url }}
**route** - Return laravel route path. Ex: {{ 'page' | route: 'slug' }}
**crop** - Crop (and/or convert) image. Ex: {{ this.images\[0\].url | crop: 300,300,'webp',75 }}
**webp** - Convert an image into webp format. Ex: {{ this.images\[0\].url | webp }}
**site\_setting** - Get site settings parameters. Ex: {{ 'mail' | site\_setting: 'to\_address' }} **menu** - Render a menu. Ex: {{ 'main-menu' | menu: 'template.menus.main' }}
**block** - Render a block. Ex: {{ 'top-line' | block }}
**form** - Render a form. Ex: {{ 'callback-form' | form: 'Form subject','-callback' }}
**trans** - Translate string using current locale. Ex: {{ '\[\[en\]\]English string\[\[ru\]\]Russian string' | trans }}
**lang** -- Translate string using language files. Ex: {{ 'auth.password' | lang }}
**view** -- Render blade view using Data vars. Ex: {{ data | view: 'template.partials.portfolio-list' }}
**service** -- Get data using service method (and pass it to the View). Ex: {{ 'getPortfolio' | service: '\\App\\Services\\DataService' | view: 'template.partials.portfolio-list' }}

Custom Liquid filters
---------------------

[](#custom-liquid-filters)

You can add your own liquid filters using a custom class. You should add this class to the configuration:
**'template\_filters' =&gt; 'App\\Template\\TemplateFilters'**

```
