Lamotivo Website Manager is a Laravel package that offers a front-end part of the project and it may be used along with Lamotivo Admin Panel.
Main features:
Lamotivo Website Manager works with Laravel 5.4+ or Laravel 6.
Require the package:
composer require lamotivo/website
Publish some configuration and migration files:
php artisan vendor:publish --provider="Lamotivo\Themes\ThemeServiceProvider" --tag=config
php artisan vendor:publish --provider="Lamotivo\Assets\AssetServiceProvider" --tag=config
php artisan vendor:publish --provider="Lamotivo\Uploads\UploadServiceProvider" --tag=config
php artisan vendor:publish --provider="Lamotivo\Uploads\UploadServiceProvider" --tag=migrations
php artisan vendor:publish --provider="Lamotivo\Website\SiteServiceProvider" --tag=config
php artisan vendor:publish --provider="Lamotivo\Website\SiteServiceProvider" --tag=website-migrations
Add to the end of your routes/web.php
file:
// your routes
Website::routes();
Add to your App\Providers\AppServiceProvider
file:
use Website;
public function boot()
{
Website::boot();
}
The default configuration file is config/website.php
, each option is well documented.
Lamotivo Website utilizes Lamotivo Themes as a core front-end interface.
Lamotivo Website ships the website::
Blade's namespaced views.
The default layout is website::layout.app
. All pages should extend it:
@extends('website::layouts.app')
@section('content')
<h1>Page Header</h1>
<p>Page content goes here...</p>
@endsection
When you create a theme, typically you should override the Websites's website::partials.header
, website::partials.content
and website::partials.footer
views by placing them in the views/vendor/website/partials
directory of your theme.
Lamotivo Website supports 2 page drivers: file
and eloquent
.
Page provider list is configured at the website.providers
configuration option. Each provider describes some options:
driver
- supported values are file
and eloquent
path
- a directory where page files are stored, e.g. resource_path('pages')
model
- a Eloquent model as a source of pages, e.g. Lamotivo\Website\Content\Page::class
prefix
- a URL prefixcache_time
- this value is used to cache page slugs for routingThe website.default_provider
option sets a default page provider. It is mostly important, if you use pages without a special URL prefix.
This driver uses static files as a source of pages.
By default configuration static pages are placed in the resources/pages
directory. You may change this, as you wish.
The file format is Markdown.
This driver uses an Eloquent model as a source of pages.
Your website may have multiple menus. Each menu is a class that extends the Lamotivo\Website\Navigation\Menu
class.
To generate a menu use the make:menu
Artisan command:
php artisan make:menu MainMenu
The freshly create Website menu will have the App\Menu
namespace and will be placed in the app/Menu
directory.
To populate menu items you should use the __constuct
method with calling the menu's add
method:
public function __construct()
{
$this->add(['url' => '/', 'anchor' => 'Home']);
}
You may define a submenu, as well:
$this->add([
'url' => '/about',
'anchor' => 'About us',
'items' => [
['url' => '/about/company', 'anchor' => 'Our Company'],
['url' => '/about/jobs', 'anchor' => 'Jobs'],
],
]);
Once you have created a menu, you are ready to attach it to the Website configuration, you may use this menu in the menus
configuration of your website.php
configuration file:
'menus' => [
'main' => App\Menu\MainMenu::class,
],
Alternatively, you may register a menu in your code:
Website::menu()->register('main', \App\Menu\MainMenu::class)
At your Blade views you may use the @website_menu
helper to render your menu. This helper accepts a menu name as the first argument. If no argument is passed, the website.default_menu
menu will be used.
Breadcrumbs are an important part of almost every website. These navigation aids don't just tell people wgere they are on your website, but they alsow help search engines work out how your site is structured.
To populate your breadcrumb navigation with link items you should use the Breadcrumb Manager:
Website::breadcrumb()->link(url('/'), 'Home')
->link(route('products'), 'Products')
->link(route('product', $product), $product->name);
At your views you may use the @website_breadcrumb
Blade helper to render your breadcrumb navigation.
Website offers a Meta Manager that allows you to handle any meta tags on your website page.
To fill SEO meta tags you may use the fill
Meta Manager method and pass an Eloquent model as the first argument.
Website::meta()->fill($page);
The Eloquent model should use the Lamotivo\Website\Seo\SeoMetaTrait
trait.
Also, you may assign meta tags using the Website::meta('key', 'value')
construction. The valid keys are:
title
- a value for the title tagdescription
- a value for the meta description tagrobots
- a value for the meta robots tagkeywords
- a value for the meta keywords tagogUrl
- a value for the OpenGraph url, if omitted, the current url is usedogSiteName
- a value for the OpenGraph urlogType
- a value for the OpenGraph urlogTitle
- a value for the OpenGraph title, if omitted, the title value is usedogDescription
- a value for the OpenGraph description, if omitted, the description value is usedogLocale
- a value for the OpenGraph localeogImage
- a value for the OpenGraph imageogImageType
- a value for the OpenGraph image typeogImageWidth
- a value for the OpenGraph image widthogImageHeight
- a value for the OpenGraph image heightogImageSecureUrl
- a value for the OpenGraph image secure URLtwitterCard
- a value for the Twitter cardtwitterSite
- a value for the Twitter sitetwitterCreator
- a value for the Twitter creatortwitterTitle
- a value for the Twitter title, if omitted, the title value is usedtwitterDescription
- a value for the Twitter description, if omitted, the description value is usedtwitterImage
- a value for the Twitter imageOf course, you are free to add any other meta tag, if needed:
Website::meta()->meta($tagName, $tagValue);
Meta Manager allows you to handle link and script tags, too:
Website::meta()->link('icon', '/favicon.png')
->attributes([
'sizes' => '16x16',
'type' => 'image/png',
]);
Website::meta()->link('stylesheet', '/some.css');
Website::meta()->link('alternate', '/rss.xml');
Website::meta()->script('<script src="/some.js" async></script>');
Some common links have shortcuts:
Website::meta()->ampLink($prefix, $url)
Website::meta()->icon($href, array $attributes)
Website::meta()->shortcutIcon($href, array $attributes = [])
Website::meta()->alternate($href, array $attributes = [])
Website::meta()->stylesheet($href, array $attributes = [])
Website::meta()->next($href, array $attributes = [])
Website::meta()->prev($href, array $attributes = [])
Website::meta()->search($href, array $attributes = [])
Website::meta()->prefetch($href, array $attributes = [])
Website::meta()->dnsPrefetch($href, array $attributes = [])
Website::meta()->preload($href, array $attributes = [])
Website::meta()->preconnect($href, array $attributes = [])
Website::meta()->manifest($href, array $attributes = [])
Website::meta()->canonical($href)
You may setup default meta values at the website.meta
configuration option.
Form Manager handles forms on your website.
Forms are stored in the app/Forms
directory.
Form classes must extend the Lamotivo\Website\Forms\Form
class.
Once you have created a form, you are ready to attach it to the Website configuration, you may use this form in the forms
configuration of your website.php
configuration file:
'forms' => [
'order' => App\Forms\OrderForm::class,
],
Alternatively, you may register a form in your code:
Website::form()->register('order', \App\Forms\OrderForm::class)
At your views you may use the @website_form('order')
Blade helper to render your form. This helper accepts a form name as the first argument.
Using old dynamic Blade helpers, such as like @form_order
, is deprecated by now.
Widget Manager handles widgets on your website.
Widgets are stored in the app/Widgets
directory.
Widget classes must extend the Lamotivo\Website\Widgets\Widget
class.
Once you have created a widget, you are ready to attach it to the Website configuration, you may use this form in the widgets
configuration of your website.php
configuration file:
'widgets' => [
'socials' => App\Widgets\SocialSharing::class,
],
Alternatively, you may register a widget in your code:
Website::form()->register('socials', \App\Widgets\SocialSharing::class)
At your Blade views you may use the @website_widget('socials')
helper to render your widget. This helper accepts a widget name as the first argument.
Using old dynamic Blade helpers, such as like @widget_socials
, is deprecated by now.
Repository Manager handles javascript repositories on your website.
Repositories are stored in the app/Supplements
directory.
Repository classes must extend the Lamotivo\Website\Supplement\Repository
class.
<?php
namespace App\Supplements;
use Illuminate\Http\Request;
use Lamotivo\Website\Supplement\Repository;
use App\Order;
use App\Product;
class ShopRepository extends Repository
{
/**
* The repository name.
*
* @var string
*/
protected static $name = 'shop';
/**
* Autoload the repository.
*
* @var boolean
*/
protected $autoload = true;
/**
* Get a configuration of the repository.
*
* @return array
*/
public function getConfig()
{
return [
// `interval` define an auto reload data
'interval' => 0, // seconds
// `actions` is an array of available actions, defined in this repository as public methods
'actions' => [
'get_info',
'buy',
],
];
}
/**
* Get additional info on products.
*
* @return array
*/
public function get_info(Request $request)
{
return [
'info' => Product::find($request->product_id),
];
}
/**
* Buy a product.
*
* @return array
*/
public function buy(Request $request)
{
$order = Order::create([
'product_id' => $request->product_id,
]);
return [
// `redirect_url` is used to make a redirect to another location
'redirect_url' => route('order', $order->id),
];
}
/**
* Boot repository data.
*
* @return void
*/
protected function boot()
{
$this->products = Product::select('id', 'name', 'price')->paginate();
}
}
Once you have created a repository, you are ready to attach it to the Website configuration, you may use this form in the repositories
configuration of your website.php
configuration file:
'repositories' => [
'shop' => App\Supplements\Shop::class,
],
Alternatively, you may register a repository in your code:
Website::form()->register('shop', \App\Supplements\Shop::class)
All your registered repositories are rendered automatically on HTML document.
In your Javascript application controller, you may use the $rep
dependency as in an example below:
websiteApp.controller('ShopController', [
'$scope',
'$rep',
function($scope, $rep) {
$scope.shop = $rep.shop;
$scope.reload = function()
{
$rep.shop.reload();
}
$scope.nextPage = function()
{
var page = $rep.shop.products.current_page;
if (page && $rep.shop.products.last_page > page)
{
page++;
$rep.shop.reload(null, {page: page});
}
}
$scope.loadNext = function()
{
$rep.shop.appendNext('products');
}
$scope.buy = function(product)
{
$rep.shop.buy({ product_id: product.id });
}
$scope.getInfo = function(product)
{
$rep.shop.get_info({ product_id: product.id });
}
}
]);
The controller view:
<div class="products">
<div class="product-item"
ng-repeat="product in shop.products.data">
<div class="product-name"
ng-bind="product.name"></div>
<div class="product-price"
ng-bind="product.price"></div>
<button class="product-buy-button"
ng-click="buy(product)"
ng-disabled="shop.buy__is_loading">Buy</button>
<button class="product-info-button"
ng-click="getInfo(product)"
ng-disabled="shop.get_info__is_loading">Info</button>
</div>
<div class="product-info"
ng-if="shop.info"
ng-bind="shop.info.description"></div>
<div class="product-buttons">
<button class="product-more-button"
ng-click="loadNext()"
ng-disabled="shop.next__is_loading">Load more</button>
<button class="product-next-button"
ng-click="nextPage()"
ng-disabled="shop.reload__is_loading">Next Page</button>
</div>
</div>
Export Manager handles your RSS feed exports. Of course, you are not limited to generate only RSS feeds, you may generate any desired exports with this manager.
To create an feed definition use the make:export
Artisan command:
php artisan make:export Rss
Export definitions are stored in the app/Export
directory. You may populate link items at the seed
method.
Once you have created an export, you are ready to attach it to the Website configuration, you may use this form in the export.feeds
configuration of your website.php
configuration file:
'export' => [
'path' => 'export',
'feeds' => [
'rss' => App\Export\Rss::class,
]
],
By default, all generated feeds are stored in the public/export
directory, as of the website.export.path
option.
You still need to provide a link to an RSS feed using Meta Manager:
Website::meta()->alternate(url('export/rss.xml'));
Or just configure it at the website.meta.links
option value.
To start the feed generation, you should run the dump:export
Artisan command:
php artisan dump:export
This command will dump all your feeds to the public/export
directory.
If you wish to process only one feed, you may pass the feed name to the command:
php artisan dump:export --feed=rss
Sitemap Manager handles your XML sitemaps.
To create a sitemap definition use the make:sitemap
Artisan command:
php artisan make:sitemap CatalogSitemap
Sitemap definitions are stored in the app/Sitemap
directory. You may populate link items at the seed
method.
Once you have created a sitemap, you are ready to attach it to the Website configuration, you may use this form in the sitemap.maps
configuration of your website.php
configuration file:
'sitemap' => [
'path' => 'sitemaps',
'limit' => 50000,
'maps' => [
'catalog' => App\Sitemap\CatalogSitemap::class,
]
],
By default, all generated sitemaps are stored in the public/sitemaps
directory, as of the website.sitemap.path
option.
However, you still need to add a link to a sitemap to the robots.txt
file.
To start the sitemap generation, you should run the dump:sitemap
Artisan command:
php artisan dump:sitemap
This command will dump all your sitemaps to the public/sitemaps
directory.
If you wish to process only one sitemap, you may pass the sitemap name to the command:
php artisan dump:export --map=catalog
Trackers are used to easily integrate some third-party services on your website. It may be a Google Analytics code or a Jivosite chat.
Lamotivo Website ships with a variety of tracker drivers:
google
- Google Analyticsgtm
- Google Tag Manageryandex
- Yandex.Metrikamailru
- Mail.ru counterfacebook
- Facebook pixelvkontakte
- Vkontakte retargettingjivosite
- Jivosite chatTo add a service, you need to define a tracker in the website.trackers
configuration array.
'trackers' => [
'yandex' => [
'driver' => 'yandex',
'code' => '... ID ...',
],
'google' => [
'driver' => 'google',
'code' => '... ID ...',
],
'gtm' => [
'driver' => 'gtm',
'code' => '... ID ...',
],
],
All defined trackers are rendered in your HTML automatically.
Also you are free to create your own tracker driver.
As an addition to powerfull Laravel configuration, Lamotivo Website offers online editable dynamic settings to your application.
Settings are stored in an Eloquent model, defined at the website.settings.model
configuration value. By default it is set to the Lamotivo\Website\Settings\Setting
class.
Settings are merged with your application configuration, when calling Website::boot()
. So you can use dynamic settings via the config()
helper, as well.
If you use a Lamotivo admin panel to manage your website, you may create a Lamotivo component based on the provided Configurator component.
<?php
namespace App\Lm\Components;
use Illuminate\Http\Request;
use Anyspin\Lamotivo\Fields\Text;
use Lamotivo\Website\Lm\Components\Configurator;
class WebsiteSettings extends Configurator
{
protected static $menu_label = 'Website Settings';
protected static $base_url = 'website-settings';
public function settings()
{
return [
Text::make('website.company.name', 'Company Name'),
Text::make('website.company.email', 'Company E-mail'),
];
}
}
Once you have created a component, you should add it to the Lamotivo menu:
lm()->menu()->component(App\Lm\Components\WebsiteSettings::class);