add seo
This commit is contained in:
25
app/Console/Commands/FixSlug.php
Normal file
25
app/Console/Commands/FixSlug.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Shop\Article;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class FixSlug extends Command
|
||||
{
|
||||
protected $signature = 'FixSlug';
|
||||
|
||||
protected $description = 'Slugify articles';
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$articles = Article::all();
|
||||
foreach ($articles as $article) {
|
||||
$article->slug = null;
|
||||
$article->update(['name' => $article->name]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,12 @@ class ArticleController extends Controller
|
||||
return response()->json(Articles::autocomplete($str));
|
||||
}
|
||||
|
||||
public function showBySlug($slug)
|
||||
{
|
||||
$id = Articles::getIDBySlug($slug);
|
||||
return $id ? $this->show($id) : view('errors.404');
|
||||
}
|
||||
|
||||
public function show($id)
|
||||
{
|
||||
$data = [
|
||||
|
||||
@@ -17,7 +17,6 @@ class StoreVariationPost extends FormRequest
|
||||
'package_id' => 'required',
|
||||
'quantity' => 'required',
|
||||
'unity_id' => 'required',
|
||||
'weight' => 'required',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Models\Botanic\Specie;
|
||||
use App\Models\Botanic\Variety;
|
||||
use App\Traits\Model\HasComments;
|
||||
use App\Traits\Model\Imageable;
|
||||
use Cviebrock\EloquentSluggable\Sluggable;
|
||||
use Fico7489\Laravel\EloquentJoin\Traits\EloquentJoin;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
@@ -16,6 +17,8 @@ use Illuminate\Database\Eloquent\Relations\MorphToMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Kirschbaum\PowerJoins\PowerJoins;
|
||||
use Laravel\Scout\Searchable;
|
||||
use RalphJSmit\Laravel\SEO\Support\HasSEO;
|
||||
use RalphJSmit\Laravel\SEO\Support\SEOData;
|
||||
use Rinvex\Categories\Traits\Categorizable;
|
||||
use Rinvex\Tags\Traits\Taggable;
|
||||
use Spatie\MediaLibrary\HasMedia;
|
||||
@@ -29,10 +32,12 @@ class Article extends Model implements HasMedia
|
||||
use EloquentJoin;
|
||||
use HasComments;
|
||||
use HasRelationships;
|
||||
use HasSEO;
|
||||
use Imageable;
|
||||
use Powerjoins;
|
||||
use RevisionableTrait;
|
||||
use Searchable;
|
||||
use Sluggable;
|
||||
use SoftDeletes;
|
||||
use Taggable;
|
||||
use UserStamps;
|
||||
@@ -177,6 +182,11 @@ class Article extends Model implements HasMedia
|
||||
return $productId ? $query->where($this->table.'.product_id', $productId) : $query;
|
||||
}
|
||||
|
||||
public function scopeBySlug($query, $slug)
|
||||
{
|
||||
return $slug ? $query->where($this->table.'.slug', $slug) : $query;
|
||||
}
|
||||
|
||||
public function scopeByTag($query, $tagId)
|
||||
{
|
||||
return $tagId ? $query->whereHas('tags', function ($query) use ($tagId) {
|
||||
@@ -227,4 +237,25 @@ class Article extends Model implements HasMedia
|
||||
'description' => html_entity_decode(strip_tags($description)),
|
||||
];
|
||||
}
|
||||
|
||||
public function getDynamicSEOData(): SEOData
|
||||
{
|
||||
// $pathToFeaturedImageRelativeToPublicPath = // ..;
|
||||
|
||||
// Override only the properties you want:
|
||||
return new SEOData(
|
||||
title: $this->name,
|
||||
description: $this->description,
|
||||
// image: $pathToFeaturedImageRelativeToPublicPath,
|
||||
);
|
||||
}
|
||||
|
||||
public function sluggable(): array
|
||||
{
|
||||
return [
|
||||
'slug' => [
|
||||
'source' => 'name'
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,9 @@
|
||||
namespace App\Repositories\Shop;
|
||||
|
||||
use App\Models\Shop\Article;
|
||||
use App\Models\Shop\Merchandise;
|
||||
use App\Repositories\Botanic\Species;
|
||||
use App\Repositories\Botanic\Varieties;
|
||||
use App\Repositories\Core\Comments;
|
||||
use App\Repositories\Core\Tag;
|
||||
use App\Traits\Model\Basic;
|
||||
use App\Traits\Repository\Imageable;
|
||||
use Illuminate\Support\Str;
|
||||
@@ -27,6 +25,11 @@ class Articles
|
||||
return $export;
|
||||
}
|
||||
|
||||
public static function getIDBySlug($slug)
|
||||
{
|
||||
return Article::bySlug($slug)->first()->id;
|
||||
}
|
||||
|
||||
public static function getOffersGroupedByNature($id, $saleChannelId = false)
|
||||
{
|
||||
$articleIds = ArticleSiblings::getSiblingsIds($id);
|
||||
@@ -178,6 +181,7 @@ class Articles
|
||||
'product_name' => $article->product->name,
|
||||
'parent_name' => trim(str_replace($article->product->name, '', $article->name)),
|
||||
'offers' => $article->offers->toArray(),
|
||||
'slug' => $article->slug,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -204,6 +204,7 @@ div.megamenu ul.megamenu li.megamenu.level1
|
||||
#navbarContent > ul > li:hover, #navbarContent > ul > li.show, #navbarContent > ul > li.active
|
||||
{
|
||||
border-bottom: 3px solid #F2B90F!important;
|
||||
margin-bottom: -3px;
|
||||
}
|
||||
|
||||
#navbarContent > ul > li > a
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
],
|
||||
"license": "proprietary",
|
||||
"require": {
|
||||
"php": "^7.4|^8.0",
|
||||
"php": "^8.1",
|
||||
"akaunting/laravel-apexcharts": "^3.0",
|
||||
"alexisgeneau/mailvalidate": "dev-master",
|
||||
"arrilot/laravel-widgets": "^3.14",
|
||||
@@ -22,6 +22,7 @@
|
||||
"coduo/php-humanizer": "^4.0",
|
||||
"composer/composer": "^2.6",
|
||||
"cornford/googlmapper": "^3.4",
|
||||
"cviebrock/eloquent-sluggable": "^9.0",
|
||||
"darryldecode/cart": "^4.2",
|
||||
"datatables/datatables": "^1.10",
|
||||
"ddzobov/laravel-pivot-softdeletes": "^2.1",
|
||||
@@ -117,6 +118,7 @@
|
||||
"fossbarrow/laravel-phpcs": "dev-main",
|
||||
"kevincobain2000/laravel-erd": "^1.6",
|
||||
"kitloong/laravel-migrations-generator": "^6.11",
|
||||
"laracraft-tech/laravel-schema-rules": "^1.3",
|
||||
"laravel/pint": "^1.13",
|
||||
"mockery/mockery": "^1.6",
|
||||
"nunomaduro/collision": "^7.10",
|
||||
|
||||
121
config/health.php
Normal file
121
config/health.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
/*
|
||||
* A result store is responsible for saving the results of the checks. The
|
||||
* `EloquentHealthResultStore` will save results in the database. You
|
||||
* can use multiple stores at the same time.
|
||||
*/
|
||||
'result_stores' => [
|
||||
Spatie\Health\ResultStores\EloquentHealthResultStore::class => [
|
||||
'connection' => env('HEALTH_DB_CONNECTION', env('DB_CONNECTION')),
|
||||
'model' => Spatie\Health\Models\HealthCheckResultHistoryItem::class,
|
||||
'keep_history_for_days' => 5,
|
||||
],
|
||||
|
||||
/*
|
||||
Spatie\Health\ResultStores\CacheHealthResultStore::class => [
|
||||
'store' => 'file',
|
||||
],
|
||||
|
||||
Spatie\Health\ResultStores\JsonFileHealthResultStore::class => [
|
||||
'disk' => 's3',
|
||||
'path' => 'health.json',
|
||||
],
|
||||
|
||||
Spatie\Health\ResultStores\InMemoryHealthResultStore::class,
|
||||
*/
|
||||
],
|
||||
|
||||
/*
|
||||
* You can get notified when specific events occur. Out of the box you can use 'mail' and 'slack'.
|
||||
* For Slack you need to install laravel/slack-notification-channel.
|
||||
*/
|
||||
'notifications' => [
|
||||
/*
|
||||
* Notifications will only get sent if this option is set to `true`.
|
||||
*/
|
||||
'enabled' => true,
|
||||
|
||||
'notifications' => [
|
||||
Spatie\Health\Notifications\CheckFailedNotification::class => ['mail'],
|
||||
],
|
||||
|
||||
/*
|
||||
* Here you can specify the notifiable to which the notifications should be sent. The default
|
||||
* notifiable will use the variables specified in this config file.
|
||||
*/
|
||||
'notifiable' => Spatie\Health\Notifications\Notifiable::class,
|
||||
|
||||
/*
|
||||
* When checks start failing, you could potentially end up getting
|
||||
* a notification every minute.
|
||||
*
|
||||
* With this setting, notifications are throttled. By default, you'll
|
||||
* only get one notification per hour.
|
||||
*/
|
||||
'throttle_notifications_for_minutes' => 60,
|
||||
'throttle_notifications_key' => 'health:latestNotificationSentAt:',
|
||||
|
||||
'mail' => [
|
||||
'to' => 'your@example.com',
|
||||
|
||||
'from' => [
|
||||
'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
|
||||
'name' => env('MAIL_FROM_NAME', 'Example'),
|
||||
],
|
||||
],
|
||||
|
||||
'slack' => [
|
||||
'webhook_url' => env('HEALTH_SLACK_WEBHOOK_URL', ''),
|
||||
|
||||
/*
|
||||
* If this is set to null the default channel of the webhook will be used.
|
||||
*/
|
||||
'channel' => null,
|
||||
|
||||
'username' => null,
|
||||
|
||||
'icon' => null,
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
* You can let Oh Dear monitor the results of all health checks. This way, you'll
|
||||
* get notified of any problems even if your application goes totally down. Via
|
||||
* Oh Dear, you can also have access to more advanced notification options.
|
||||
*/
|
||||
'oh_dear_endpoint' => [
|
||||
'enabled' => false,
|
||||
|
||||
/*
|
||||
* When this option is enabled, the checks will run before sending a response.
|
||||
* Otherwise, we'll send the results from the last time the checks have run.
|
||||
*/
|
||||
'always_send_fresh_results' => true,
|
||||
|
||||
/*
|
||||
* The secret that is displayed at the Application Health settings at Oh Dear.
|
||||
*/
|
||||
'secret' => env('OH_DEAR_HEALTH_CHECK_SECRET'),
|
||||
|
||||
/*
|
||||
* The URL that should be configured in the Application health settings at Oh Dear.
|
||||
*/
|
||||
'url' => '/oh-dear-health-check-results',
|
||||
],
|
||||
|
||||
/*
|
||||
* You can set a theme for the local results page
|
||||
*
|
||||
* - light: light mode
|
||||
* - dark: dark mode
|
||||
*/
|
||||
'theme' => 'light',
|
||||
|
||||
/*
|
||||
* When enabled, completed `HealthQueueJob`s will be displayed
|
||||
* in Horizon's silenced jobs screen.
|
||||
*/
|
||||
'silence_health_queue_job' => true,
|
||||
];
|
||||
158
config/sluggable.php
Normal file
158
config/sluggable.php
Normal file
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/**
|
||||
* What attributes do we use to build the slug?
|
||||
* This can be a single field, like "name" which will build a slug from:
|
||||
*
|
||||
* $model->name;
|
||||
*
|
||||
* Or it can be an array of fields, like ["name", "company"], which builds a slug from:
|
||||
*
|
||||
* $model->name . ' ' . $model->company;
|
||||
*
|
||||
* If you've defined custom getters in your model, you can use those too,
|
||||
* since Eloquent will call them when you request a custom attribute.
|
||||
*
|
||||
* Defaults to null, which uses the toString() method on your model.
|
||||
*/
|
||||
|
||||
'source' => null,
|
||||
|
||||
/**
|
||||
* The maximum length of a generated slug. Defaults to "null", which means
|
||||
* no length restrictions are enforced. Set it to a positive integer if you
|
||||
* want to make sure your slugs aren't too long.
|
||||
*/
|
||||
|
||||
'maxLength' => null,
|
||||
|
||||
/**
|
||||
* If you are setting a maximum length on your slugs, you may not want the
|
||||
* truncated string to split a word in half. The default setting of "true"
|
||||
* will ensure this, e.g. with a maxLength of 12:
|
||||
*
|
||||
* "my source string" -> "my-source"
|
||||
*
|
||||
* Setting it to "false" will simply truncate the generated slug at the
|
||||
* desired length, e.g.:
|
||||
*
|
||||
* "my source string" -> "my-source-st"
|
||||
*/
|
||||
|
||||
'maxLengthKeepWords' => true,
|
||||
|
||||
/**
|
||||
* If left to "null", then use the cocur/slugify package to generate the slug
|
||||
* (with the separator defined below).
|
||||
*
|
||||
* Set this to a closure that accepts two parameters (string and separator)
|
||||
* to define a custom slugger. e.g.:
|
||||
*
|
||||
* 'method' => function( $string, $sep ) {
|
||||
* return preg_replace('/[^a-z]+/i', $sep, $string);
|
||||
* },
|
||||
*
|
||||
* Otherwise, this will be treated as a callable to be used. e.g.:
|
||||
*
|
||||
* 'method' => array('Str','slug'),
|
||||
*/
|
||||
|
||||
'method' => null,
|
||||
|
||||
/**
|
||||
* Separator to use when generating slugs. Defaults to a hyphen.
|
||||
*/
|
||||
|
||||
'separator' => '-',
|
||||
|
||||
/**
|
||||
* Enforce uniqueness of slugs? Defaults to true.
|
||||
* If a generated slug already exists, an incremental numeric
|
||||
* value will be appended to the end until a unique slug is found. e.g.:
|
||||
*
|
||||
* my-slug
|
||||
* my-slug-1
|
||||
* my-slug-2
|
||||
*/
|
||||
|
||||
'unique' => true,
|
||||
|
||||
/**
|
||||
* If you are enforcing unique slugs, the default is to add an
|
||||
* incremental value to the end of the base slug. Alternatively, you
|
||||
* can change this value to a closure that accepts three parameters:
|
||||
* the base slug, the separator, and a Collection of the other
|
||||
* "similar" slugs. The closure should return the new unique
|
||||
* suffix to append to the slug.
|
||||
*/
|
||||
|
||||
'uniqueSuffix' => null,
|
||||
|
||||
/**
|
||||
* What is the first suffix to add to a slug to make it unique?
|
||||
* For the default method of adding incremental integers, we start
|
||||
* counting at 2, so the list of slugs would be, e.g.:
|
||||
*
|
||||
* - my-post
|
||||
* - my-post-2
|
||||
* - my-post-3
|
||||
*/
|
||||
'firstUniqueSuffix' => 2,
|
||||
|
||||
/**
|
||||
* Should we include the trashed items when generating a unique slug?
|
||||
* This only applies if the softDelete property is set for the Eloquent model.
|
||||
* If set to "false", then a new slug could duplicate one that exists on a trashed model.
|
||||
* If set to "true", then uniqueness is enforced across trashed and existing models.
|
||||
*/
|
||||
|
||||
'includeTrashed' => false,
|
||||
|
||||
/**
|
||||
* An array of slug names that can never be used for this model,
|
||||
* e.g. to prevent collisions with existing routes or controller methods, etc..
|
||||
* Defaults to null (i.e. no reserved names).
|
||||
* Can be a static array, e.g.:
|
||||
*
|
||||
* 'reserved' => array('add', 'delete'),
|
||||
*
|
||||
* or a closure that returns an array of reserved names.
|
||||
* If using a closure, it will accept one parameter: the model itself, and should
|
||||
* return an array of reserved names, or null. e.g.
|
||||
*
|
||||
* 'reserved' => function( Model $model) {
|
||||
* return $model->some_method_that_returns_an_array();
|
||||
* }
|
||||
*
|
||||
* In the case of a slug that gets generated with one of these reserved names,
|
||||
* we will do:
|
||||
*
|
||||
* $slug .= $separator + "1"
|
||||
*
|
||||
* and continue from there.
|
||||
*/
|
||||
|
||||
'reserved' => null,
|
||||
|
||||
/**
|
||||
* Whether to update the slug value when a model is being
|
||||
* re-saved (i.e. already exists). Defaults to false, which
|
||||
* means slugs are not updated.
|
||||
*
|
||||
* Be careful! If you are using slugs to generate URLs, then
|
||||
* updating your slug automatically might change your URLs which
|
||||
* is probably not a good idea from an SEO point of view.
|
||||
* Only set this to true if you understand the possible consequences.
|
||||
*/
|
||||
|
||||
'onUpdate' => false,
|
||||
|
||||
/**
|
||||
* If the default slug engine of cocur/slugify is used, this array of
|
||||
* configuration options will be used when instantiating the engine.
|
||||
*/
|
||||
'slugEngineOptions' => [],
|
||||
|
||||
];
|
||||
@@ -15,15 +15,16 @@ return new class extends Migration
|
||||
{
|
||||
Schema::create('shop_articles', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->unsignedInteger('article_nature_id')->nullable()->index('family_id');
|
||||
$table->unsignedInteger('article_nature_id')->nullable()->index('article_nature_id');
|
||||
$table->string('product_type', 100)->nullable();
|
||||
$table->unsignedInteger('product_id')->nullable();
|
||||
$table->string('ref', 50)->nullable()->unique('ref');
|
||||
$table->string('name')->nullable();
|
||||
$table->string('slug')->nullable()->unique('slug');
|
||||
$table->unsignedInteger('hash')->nullable();
|
||||
$table->text('description')->nullable();
|
||||
$table->tinyInteger('visible')->nullable();
|
||||
$table->unsignedTinyInteger('homepage')->nullable();
|
||||
$table->tinyInteger('visible')->nullable()->index('visible');
|
||||
$table->unsignedTinyInteger('homepage')->nullable()->index('homepage');
|
||||
$table->unsignedSmallInteger('created_by')->nullable();
|
||||
$table->unsignedSmallInteger('updated_by')->nullable();
|
||||
$table->unsignedSmallInteger('deleted_by')->nullable();
|
||||
|
||||
@@ -18,8 +18,8 @@ return new class extends Migration
|
||||
$table->unsignedInteger('category_id')->nullable()->index('category_id');
|
||||
$table->string('name', 50)->nullable();
|
||||
$table->text('description')->nullable();
|
||||
$table->tinyInteger('visible')->nullable();
|
||||
$table->unsignedTinyInteger('homepage')->nullable();
|
||||
$table->tinyInteger('visible')->nullable()->index('visible');
|
||||
$table->unsignedTinyInteger('homepage')->nullable()->index('homepage');
|
||||
$table->unsignedSmallInteger('created_by')->nullable();
|
||||
$table->unsignedSmallInteger('updated_by')->nullable();
|
||||
$table->unsignedSmallInteger('deleted_by')->nullable();
|
||||
|
||||
@@ -17,7 +17,7 @@ return new class extends Migration
|
||||
$table->increments('id');
|
||||
$table->unsignedInteger('tariff_id')->nullable()->index('tariff_id');
|
||||
$table->unsignedInteger('sale_channel_id')->nullable()->index('sale_channel_id');
|
||||
$table->unsignedTinyInteger('status_id')->nullable();
|
||||
$table->unsignedTinyInteger('status_id')->nullable()->index('status_id');
|
||||
$table->string('name', 100)->nullable();
|
||||
$table->unsignedSmallInteger('created_by')->nullable();
|
||||
$table->unsignedSmallInteger('updated_by')->nullable();
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
{{ Form::open(['route' => 'Admin.Shop.Articles.store', 'id' => 'article-form', 'autocomplete' => 'off', 'files' => true]) }}
|
||||
{{ Form::open([
|
||||
'route' => 'Admin.Shop.Articles.store',
|
||||
'id' => 'article-form',
|
||||
'autocomplete' => 'off',
|
||||
'files' => true,
|
||||
]) }}
|
||||
<input type="hidden" name="id" id="id" value="{{ $article['id'] ?? null }}">
|
||||
@include('Admin.Shop.Articles.partials.characteristics')
|
||||
{{ Form::close() }}
|
||||
|
||||
@@ -34,14 +34,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
@include('components.form.input', [
|
||||
'name' => 'weight',
|
||||
'value' => $variation['weight'] ?? false,
|
||||
'required' => true,
|
||||
'label' => 'Poids',
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<div class="card">
|
||||
<a href="{{ route('Shop.Articles.show', ['id' => $article['id'] ?? false ]) }}" class="green-dark">
|
||||
<a href="{{ route('Shop.Articles.slug', ['slug' => $article['slug'] ?? false]) }}" class="green-dark">
|
||||
<div class="content">
|
||||
<div class="content-overlay"></div>
|
||||
<img class="content-image card-img-top"
|
||||
src="{{ App\Repositories\Shop\Articles::getPreviewSrc($article['image'] ?? false) }}" alt="{{ $product_name }}">
|
||||
src="{{ App\Repositories\Shop\Articles::getPreviewSrc($article['image'] ?? false) }}"
|
||||
alt="{{ $product_name }}">
|
||||
<div class="content-details fadeIn-bottom">
|
||||
<h3 class="content-title d-none"></h3>
|
||||
<p class="content-text">{!! Str::limit($article['description'], 500) !!}</p>
|
||||
@@ -11,7 +12,7 @@
|
||||
</div>
|
||||
</a>
|
||||
<div class="card-body p-2 pb-1">
|
||||
<a href="{{ route('Shop.Articles.show', ['id' => $article['id'] ?? false ]) }}" class="green-dark">
|
||||
<a href="{{ route('Shop.Articles.slug', ['slug' => $article['slug'] ?? false]) }}" class="green-dark">
|
||||
<div class="row card-title">
|
||||
<div class="col-12 green">
|
||||
<div class="text-truncate mb-0" style="font-size: 1.3em;">{{ $article['parent_name'] }}</div>
|
||||
@@ -27,6 +28,7 @@
|
||||
Ajout rapide
|
||||
</button>
|
||||
@break
|
||||
|
||||
@case(2)
|
||||
<button type="button" class="btn btn-link bg-green text-white w-100 basket"
|
||||
data-id="{{ $article['plants']['id'] ?? false }}">
|
||||
|
||||
@@ -5,10 +5,14 @@
|
||||
<h1 class="p-2 green" style="font-size: 2em;">{{ $shelve['name'] }}</h1>
|
||||
</div>
|
||||
<div class="col-6 text-right">
|
||||
<a href="{{ route('Shop.Categories.show', ['id' => $shelve['id']]) }}" class="mt-2 btn btn-green-dark" >
|
||||
<a href="{{ route('Shop.Categories.show', ['id' => $shelve['id']]) }}"
|
||||
class="mt-2 mr-2 btn btn-green-dark">
|
||||
Découvrir la sélection
|
||||
</a>
|
||||
<a class="mt-2 green-dark btn" href="{{ route('Shop.Categories.show', ['id' => $shelve['id']]) }}">Tout voir</a>
|
||||
<!--
|
||||
<a class="mt-2 green-dark btn" href="{{ route('Shop.Categories.show', ['id' => $shelve['id']]) }}">Tout
|
||||
voir</a>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
@@ -16,8 +20,11 @@
|
||||
@foreach ($shelve['articles'] as $name => $article)
|
||||
<div class="text-center pr-2 pl-2">
|
||||
<a class="green" href="{{ route('Shop.Articles.show', ['id' => $article['id']]) }}">
|
||||
<img data-lazy="{{ App\Repositories\Shop\Articles::getPreviewSrc($article['image'] ?? false) }}" class="d-block w-100 rounded" alt="{{ $name }}"/>
|
||||
<img data-lazy="{{ App\Repositories\Shop\Articles::getPreviewSrc($article['image'] ?? false) }}"
|
||||
class="d-block w-100 rounded" alt="{{ $name }}" />
|
||||
<div style="height: 48px;">
|
||||
{{ $name }}
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
@endforeach
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
@endphp
|
||||
|
||||
<div class="container p-0">
|
||||
<div class="row m-0 shadow bg-white p-2 w-100 @if ( in_array($menu['id'], [$category['id'] ?? false, $category['parent_id'] ?? false])) active @endif">
|
||||
<div class="row m-0 shadow bg-white p-2 w-100 @if (in_array($menu['id'], [$category['id'] ?? false, $category['parent_id'] ?? false])) active @endif">
|
||||
<div class="col mb-4">
|
||||
<a class="green-dark" href="{{ route('Shop.Categories.show', ['id' => $menu['id']]) }}">
|
||||
<div class="w-100"><strong>Tous les articles</strong></div>
|
||||
|
||||
@@ -2,5 +2,6 @@
|
||||
|
||||
Route::prefix('Articles')->name('Articles.')->group(function () {
|
||||
Route::any('autocomplete/{q?}', 'ArticleController@autocomplete')->name('autocomplete');
|
||||
Route::get('show/{id}', 'ArticleController@show')->name('show');
|
||||
Route::get('show/{id?}', 'ArticleController@show')->name('show');
|
||||
Route::get('voir/{slug?}', 'ArticleController@showBySlug')->name('slug');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user