├── LICENSE ├── README.md ├── composer.json ├── config ├── blog-eloquent.php ├── blog-sharing.php └── blog.php ├── database ├── factories │ └── EntryFactory.php ├── migrations │ └── 2017_10_04_000000_create_blog_entries_table.php └── seeds │ ├── DefaultBlogEntrySeeder.php │ └── StylingTestEntriesSeeder.php ├── dist └── blog.css ├── phpcs.xml.dist ├── resources ├── images │ └── feed-icon.svg ├── lang │ └── en │ │ ├── feed.php │ │ ├── sharing.php │ │ └── titles.php ├── sass │ ├── _blog.scss │ ├── _grid.scss │ └── style.scss └── views │ ├── author │ └── listItem.blade.php │ ├── blog │ ├── intro.blade.php │ ├── latestEntriesLinks.blade.php │ ├── partials │ │ ├── socialSharingLink.blade.php │ │ └── socialSharingListItem.blade.php │ └── socialSharingAside.blade.php │ ├── custom │ ├── all-pages.blade.php │ ├── entry-page.blade.php │ └── index-page.blade.php │ ├── entry.blade.php │ ├── entry │ ├── full.blade.php │ ├── listItem.blade.php │ ├── partials │ │ ├── adsAside.blade.php │ │ ├── authors.blade.php │ │ ├── content.blade.php │ │ ├── footer.blade.php │ │ ├── header.blade.php │ │ ├── imageStyle.blade.php │ │ ├── nav.blade.php │ │ └── relatedContent.blade.php │ └── short.blade.php │ ├── feed.blade.php │ ├── feed │ ├── author.blade.php │ ├── entry.blade.php │ ├── metaLink.blade.php │ ├── subscriptionLink.blade.php │ └── summaryFooter.blade.php │ ├── index.blade.php │ └── layouts │ ├── blog.blade.php │ └── html.blade.php ├── routes └── web.php └── src ├── Blog.php ├── BlogRegistry.php ├── BlogServiceProvider.php ├── Contracts ├── Author.php ├── Blog.php ├── BlogEntry.php ├── BlogEntryProvider.php ├── BlogRegistry.php ├── MarkdownString.php ├── ProvidesBladeViewNames.php └── ProvidesTranslationKeys.php ├── Eloquent ├── AbstractBlogEntry.php ├── BlogEntry.php ├── BlogEntryProvider.php └── PublishedScope.php ├── Http └── Controllers │ ├── BaseBlogController.php │ ├── FeedController.php │ ├── ListEntriesController.php │ └── ShowEntryController.php └── Support ├── Author.php ├── CommonMarkString.php ├── HandlesRoutes.php ├── ProvidesBladeViewNames.php ├── ProvidesTranslationKeys.php ├── QueriesEntryProvider.php └── SummaryExtractor.php /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Björn Nilsved 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # laravel-blog 2 | 3 | [![Build Status](https://travis-ci.com/bjuppa/laravel-blog.svg?branch=master)](https://travis-ci.com/bjuppa/laravel-blog) 4 | 5 | This package is a flexible blogging solution that you can add to your 6 | [Laravel](https://laravel.com) app. 7 | 8 | Is takes blog entries from _storage_ and publishes them to 9 | [the Web](https://en.wikipedia.org/wiki/World_Wide_Web) 10 | in common formats for consumption by people and machines through URLs. 11 | 12 | Each blog gets: 13 | 14 | - An index page listing the latest entries 15 | - A page for each blog entry displaying its full contents 16 | - An [Atom feed]() 17 | 18 | The default storage is [Eloquent](https://laravel.com/docs/eloquent), 19 | but you can write your own `BlogEntryProvider` should you wish. 20 | Have a look at the files in 21 | [`src/Contracts`](https://github.com/bjuppa/laravel-blog/tree/master/src/Contracts) 22 | for a quick overview of the entites this package handles. 23 | 24 | ## Admin interface 25 | 26 | This package **does not** provide any admin interface for editing blog entries. 27 | There's a 28 | [separate package](https://packagist.org/packages/bjuppa/laravel-blog-admin) 29 | that can _optionally_ be installed to provide admin routes for editing blog 30 | contents. 31 | 32 | Another option is to create the mechanism to edit blog entries yourself, 33 | in your Laravel app. 34 | [Entries](https://github.com/bjuppa/laravel-blog/blob/master/src/Eloquent/BlogEntry.php) 35 | are represented by [Eloquent models](https://laravel.com/docs/eloquent) 36 | by default, so shouldn't be too hard for Laravel developers. 37 | 38 | ## Requirements 39 | 40 | You need at least **Laravel 5.6.8** to use this package. 41 | The included 42 | [entry model](https://github.com/bjuppa/laravel-blog/blob/master/src/Eloquent/BlogEntry.php) 43 | and 44 | [migration](https://github.com/bjuppa/laravel-blog/blob/master/database/migrations/2017_10_04_000000_create_blog_entries_table.php) 45 | requires a database connection supporting json-type columns. 46 | 47 | ## Usage 48 | 49 | 1. Require the package: 50 | 51 | ```bash 52 | composer require bjuppa/laravel-blog 53 | ``` 54 | 55 | The package will automatically register itself. 56 | 57 | 2. Publish the configuration file: 58 | 59 | ```bash 60 | php artisan vendor:publish --provider="Bjuppa\LaravelBlog\BlogServiceProvider" --tag="blog-config" 61 | ``` 62 | 63 | 3. Edit the published configuration file `config/blog.php` 64 | to setup your desired blogs and their options. 65 | 66 | Configurations may be changed later and more blogs can be added etc. 67 | Just remember that permalinks and generated entry IDs should ideally be 68 | kept constant after a blog has been published to avoid broken feeds and 69 | links for your audience. 70 | 71 | The service provider handles registration of routes to all configured blogs. 72 | You can check which routes and paths are generated using: 73 | 74 | ```bash 75 | php artisan route:list 76 | ``` 77 | 78 | 4. Run migrations to automatically set up any tables needed to use the 79 | configured blog entry providers: 80 | 81 | ```bash 82 | php artisan migrate 83 | ``` 84 | 85 | 5. (optional) If you want to create a default blog entry in the database you 86 | can run the seeder: 87 | 88 | ```bash 89 | php artisan db:seed --class="Bjuppa\LaravelBlog\Database\Seeds\DefaultBlogEntrySeeder" 90 | ``` 91 | 92 | 6. (optional) If you want to use the included styling, first publish the CSS 93 | to your public directory: 94 | 95 | ```bash 96 | php artisan vendor:publish --provider="Bjuppa\LaravelBlog\BlogServiceProvider" --tag="blog-styling" 97 | ``` 98 | 99 | ...then edit `config/blog.php` and add `'css/blog.css'` 100 | to the `stylesheets` config. 101 | 102 | Now visit your fresh blog in a browser! 103 | The default url path is `/blog` unless you've changed the config. 104 | 105 | ## Edit blog posts 106 | 107 | Add and edit blog entries in the database any way you like. 108 | You can create your own admin interface, write straight to the database, 109 | or perhaps use 110 | [`php artisan tinker`](https://laravel.com/docs/artisan#introduction)... 😉 111 | The model used by default is 112 | [`Bjuppa\LaravelBlog\Eloquent\BlogEntry`](https://github.com/bjuppa/laravel-blog/blob/master/src/Eloquent/BlogEntry.php). 113 | 114 | There is [a separate package providing an admin interface](#admin-interface). 115 | 116 | ### User permissions 117 | 118 | All published entries are public to *view* by anyone at their url. 119 | 120 | To enable users to *preview* unpublished entries, first create a Laravel 121 | [gate](https://laravel.com/docs/authorization#gates) or 122 | [policy](https://laravel.com/docs/authorization#creating-policies) 123 | (for your entry model) and then configure the `preview_ability` in your 124 | `config/blog.php` to match. 125 | 126 | A gate defined in your `App\Providers\AuthServiceProvider` could look like this: 127 | 128 | ```php 129 | Gate::define('preview blog entries', function ($user) { 130 | // Check for your own admin user model, or some other criteria! 131 | return $user instanceof \App\AdminUser; 132 | }); 133 | ``` 134 | 135 | ## Styling the frontend 136 | 137 | The included CSS file is built using 138 | [Kingdom CSS](https://bjuppa.github.io/kingdom/), 139 | which is yet another CSS framework, created by... yours truly. 140 | 141 | The default styling is meant to add some consistent styling to the standard 142 | HTML elements, so a blog using it will not look "designed", although it has 143 | some opinionated layout and spacing (especially on a larger screen). 144 | You could say it has a ["brutalist"](https://brutalist-web.design) approach, 145 | it even uses browsers' default fonts. 146 | 147 | ### Using the included utility classes 148 | 149 | Blog authors may want to add some special styles to elements within 150 | their entries. 151 | Some classes are useful on elements that are on the first level within 152 | entry contents: 153 | 154 | - `.full-bleed` will expand the element to cover the entire width 155 | of the viewport - great for images. 156 | - `.start-margin-bleed` and `.end-margin-bleed` will make the element extend 157 | into the left or right margin. 158 | - `.float-right` and `.float-left` will float the element in single-column view. 159 | - `.span-content` will make the element cover both columns when the screen is 160 | big enough for a two-column view - good for elements that require more 161 | space, but not the full width. 162 | - `.full-column-bleed` is similar to `.full-bleed` but will not 163 | cover multiple columns. 164 | - `.blog-related-content` will move the the element into the first available 165 | row of the second column - great for `