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/websitePublish 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-migrationsAdd 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>
@endsectionWhen 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 eloquentpath - 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::classprefix - 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 MainMenuThe 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 RssExport 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:exportThis 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=rssSitemap Manager handles your XML sitemaps.
To create a sitemap definition use the make:sitemap Artisan command:
php artisan make:sitemap CatalogSitemapSitemap 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:sitemapThis 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=catalogTrackers 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);