diff --git a/app/Page.php b/app/Page.php index 71977bd..da8cada 100755 --- a/app/Page.php +++ b/app/Page.php @@ -66,8 +66,11 @@ public function getTotallyStrippedBodyAttribute() $string = $this->attributes['body']; $doubleSpace = strip_tags(str_replace('<', ' <', $string)); $singleSpace = str_replace(' ', ' ', $doubleSpace); - - return trim($singleSpace); + $string = trim($singleSpace); + if (mb_strlen($string, "utf-8") > 150) { + $string = mb_substr($string, 0, 150, "utf-8") . '...'; + } + return $string; } /** diff --git a/app/Post.php b/app/Post.php index c8b0ef3..df7714e 100755 --- a/app/Post.php +++ b/app/Post.php @@ -107,8 +107,11 @@ public function getTotallyStrippedBodyAttribute() $string = $this->attributes['body']; $doubleSpace = strip_tags(str_replace('<', ' <', $string)); $singleSpace = str_replace(' ', ' ', $doubleSpace); - - return trim($singleSpace); + $string = trim($singleSpace); + if (mb_strlen($string, "utf-8") > 150) { + $string = mb_substr($string, 0, 150, "utf-8") . '...'; + } + return $string; } /** diff --git a/composer.json b/composer.json index 63660bb..56d6837 100644 --- a/composer.json +++ b/composer.json @@ -12,6 +12,7 @@ "fideloper/proxy": "^4.0", "guzzlehttp/guzzle": "^6.3", "intervention/image": "^2.4", + "jaybizzle/laravel-crawler-detect": "1.*", "laravel/framework": "5.6.*", "laravel/tinker": "^1.0", "mews/purifier": "^2.0", diff --git a/config/app.php b/config/app.php index 89be686..3682225 100755 --- a/config/app.php +++ b/config/app.php @@ -152,6 +152,7 @@ */ Tymon\JWTAuth\Providers\LaravelServiceProvider::class, Nutsweb\LaravelPrerender\LaravelPrerenderServiceProvider::class, + Jaybizzle\LaravelCrawlerDetect\LaravelCrawlerDetectServiceProvider::class, /* * Application Service Providers... @@ -208,7 +209,8 @@ 'Storage' => Illuminate\Support\Facades\Storage::class, 'URL' => Illuminate\Support\Facades\URL::class, 'Validator' => Illuminate\Support\Facades\Validator::class, - 'View' => Illuminate\Support\Facades\View::class + 'View' => Illuminate\Support\Facades\View::class, + 'Crawler' => Jaybizzle\LaravelCrawlerDetect\Facades\LaravelCrawlerDetect::class, ], ]; diff --git a/config/prerender.php b/config/prerender.php index c27063a..5233603 100644 --- a/config/prerender.php +++ b/config/prerender.php @@ -9,7 +9,7 @@ | prerender on your local machine. | */ - 'enable' => env('PRERENDER_ENABLE', true), + 'enable' => env('PRERENDER_ENABLE', false), /* |-------------------------------------------------------------------------- | Prerender URL diff --git a/readme.md b/readme.md index ef6e2d3..1fdec9b 100644 --- a/readme.md +++ b/readme.md @@ -1,10 +1,10 @@ # Spala -Content Management System based on [Laravel 5.6](https://laravel.com), [Vue 2.5](https://vuejs.org), [Bootstrap 4](https://getbootstrap.com/) and [Monster Admin Template](https://wrappixel.com/demos/admin-templates/monster-admin/Documentation/document.html). +Content Management System based on [Laravel 5.6](https://laravel.com), [Vue 2.5](https://vuejs.org), [Bootstrap 4](https://getbootstrap.com/) and [Monster Admin Template](https://wrappixel.com/demos/admin-templates/monster-admin/Documentation/document.html) ## Getting Started -These instructions will get you a copy of the project up and running on your local Linux or Mac OS X machine. +These instructions will get you a copy of the project up and running on your local Linux or Mac OS X machine ### Installing @@ -58,7 +58,7 @@ Execute the NPM script npm run dev ``` -Change the group ownership of the storage and cache directories and grant them all permissions (for Mac type `_www` instead of `www-data`). +Change the group ownership of the storage and cache directories and grant them all permissions (for Mac type `_www` instead of `www-data`) ``` sudo chgrp -R www-data storage bootstrap/cache @@ -71,21 +71,13 @@ Install the application (create default roles, permissions, etc.) php artisan install ``` -Go to the page `/register`. The first registered user will get the admin role. +Go to the page `/register`. The first registered user will get the admin role -If you need own prerender server for SEO purposes - -``` -git clone https://github.com/prerender/prerender.git -cd prerender -npm install -npm install -g forever -forever start server.js -``` +By default server-side rendering is used for the SEO purposes but if you need your own prerender server you can use [prerender.io](https://prerender.io/) ## Contributing -As an open project, I welcome contributions from everybody. Please, feel free to fork the repository and submit pull requests. +As an open project, I welcome contributions from everybody. Please, feel free to fork the repository and submit pull requests ## License diff --git a/resources/assets/js/views/page/View.vue b/resources/assets/js/views/page/View.vue index ac68919..382dc39 100755 --- a/resources/assets/js/views/page/View.vue +++ b/resources/assets/js/views/page/View.vue @@ -47,16 +47,16 @@ return { title: `${this.documentTitle}`, meta: [ - {name: 'description', content: this.page ? this.limitWords(this.page.totally_stripped_body) : ''}, + {name: 'description', content: this.page ? this.page.totally_stripped_body : ''}, {name: 'twitter:card', content: 'summary_large_image'}, {name: 'twitter:title', content: this.page ? this.page.title : ''}, - {name: 'twitter:description', content: this.page ? this.limitWords(this.page.totally_stripped_body) : ''}, + {name: 'twitter:description', content: this.page ? this.page.totally_stripped_body : ''}, {name: 'twitter:image', content: `${this.getConfig('app_url')}/uploads/images/cover-default.png`}, {property: 'og:type', content: 'website'}, {property: 'og:site_name', content: this.getConfig('company_name')}, {property: 'og:url', content: this.page ? `${this.getConfig('app_url')}/${this.page.slug}` : ''}, {property: 'og:title', content: this.page ? this.page.title : ''}, - {property: 'og:description', content: this.page ? this.limitWords(this.page.totally_stripped_body) : ''}, + {property: 'og:description', content: this.page ? this.page.totally_stripped_body : ''}, {property: 'og:image', content: `${this.getConfig('app_url')}/uploads/images/cover-default.png`} ] } @@ -96,9 +96,6 @@ getConfig(name) { return helper.getConfig(name); }, - limitWords(str) { - return helper.limitWords(str, 35); - }, searchCategory(categoryId) { helper.showSpinner(); this.$store.dispatch('setSearchCategory', categoryId); diff --git a/resources/assets/js/views/post/View.vue b/resources/assets/js/views/post/View.vue index a663ba8..4ca9977 100755 --- a/resources/assets/js/views/post/View.vue +++ b/resources/assets/js/views/post/View.vue @@ -50,16 +50,16 @@ return { title: `${this.documentTitle}`, meta: [ - {name: 'description', content: this.post ? this.limitWords(this.post.totally_stripped_body) : ''}, + {name: 'description', content: this.post ? this.post.totally_stripped_body : ''}, {name: 'twitter:card', content: 'summary_large_image'}, {name: 'twitter:title', content: this.post ? this.post.title : ''}, - {name: 'twitter:description', content: this.post ? this.limitWords(this.post.totally_stripped_body) : ''}, + {name: 'twitter:description', content: this.post ? this.post.totally_stripped_body : ''}, {name: 'twitter:image', content: this.post ? `${this.getConfig('app_url')}/${this.post.cover}` : ''}, {property: 'og:type', content: 'website'}, {property: 'og:site_name', content: this.getConfig('company_name')}, {property: 'og:url', content: this.post ? `${this.getConfig('app_url')}/${this.categorySlug}/${this.post.slug}` : ''}, {property: 'og:title', content: this.post ? this.post.title : ''}, - {property: 'og:description', content: this.post ? this.limitWords(this.post.totally_stripped_body) : ''}, + {property: 'og:description', content: this.post ? this.post.totally_stripped_body : ''}, {property: 'og:image', content: this.post ? `${this.getConfig('app_url')}/${this.post.cover}` : ''} ] } @@ -105,9 +105,6 @@ getConfig(name) { return helper.getConfig(name); }, - limitWords(str) { - return helper.limitWords(str, 35); - }, searchCategory(categoryId) { helper.showSpinner(); this.$store.dispatch('setSearchCategory', categoryId); diff --git a/resources/views/seo.blade.php b/resources/views/seo.blade.php new file mode 100755 index 0000000..88b5db0 --- /dev/null +++ b/resources/views/seo.blade.php @@ -0,0 +1,29 @@ + + + + + + + {{ !empty($article->title) ? $article->title . ' | ' . config('config.company_name') : config('config.company_name')}} + + + + + + + + + + + + + + + + +
+

{{ $article->title or config('config.company_name') }}

+
{!! $article->stripped_body or config('config.company_description') !!}
+
+ + diff --git a/routes/web.php b/routes/web.php index b447e05..90463d5 100755 --- a/routes/web.php +++ b/routes/web.php @@ -30,5 +30,11 @@ })->name('assets.lang'); Route::get('/{vue?}', function () { + if(Crawler::isCrawler()) { + $category = App\Category::where('slug', Request::segment(1))->first(); + if (empty($category)) return view('seo')->with('article', null); + $article = App\Post::filterByCategoryAndSlug($category, Request::segment(2))->first(); + return view('seo')->with('article', $article); + } return view('home'); })->where('vue', '[\/\w\.-]*')->name('home');