| @ -1,4 +1,5 @@ | |||
| APP_DEBUG=false | |||
| APP_LOCALE=en | |||
| DIRECTUS_API_URL= | |||
| DIRECTUS_API_TOKEN= | |||
| @ -0,0 +1,53 @@ | |||
| <?php | |||
| namespace App\Controllers; | |||
| use App\Controllers\DirectusControllerAbstract; | |||
| use App\Repositories\SiteRepository; | |||
| use App\Repositories\PostRepository; | |||
| /** | |||
| * controller for render feed of posts | |||
| * | |||
| * | |||
| * @author Björn Hase, Tentakelfabrik | |||
| * @license http://opensource.org/licenses/MIT The MIT License | |||
| * @link https://gitea.tentakelfabrik.de/Tentakelfabrik/super-gear-directus | |||
| * | |||
| */ | |||
| class FeedController extends DirectusControllerAbstract | |||
| { | |||
| private $limit = 20; | |||
| /** | |||
| * | |||
| */ | |||
| protected $page = [ | |||
| 'data' => [ | |||
| 'view' => 'rss' | |||
| ] | |||
| ]; | |||
| /** | |||
| * get single page from slug | |||
| * | |||
| * | |||
| * @param string $slug | |||
| */ | |||
| public function indexAction() | |||
| { | |||
| $siteRepository = new SiteRepository(); | |||
| $site = $siteRepository->findOne(); | |||
| $postRepository = new PostRepository(); | |||
| $posts = $postRepository->find($this->limit); | |||
| // change type | |||
| header('Content-Type: text/xml'); | |||
| $this->render($this->page, [ | |||
| 'site' => $site, | |||
| 'posts' => $posts | |||
| ]); | |||
| } | |||
| } | |||
| @ -0,0 +1,36 @@ | |||
| <?php | |||
| namespace App\Controllers; | |||
| use App\Controllers\DirectusControllerAbstract; | |||
| use App\Repositories\PostRepository; | |||
| /** | |||
| * controller for page items from directus | |||
| * | |||
| * | |||
| * @author Björn Hase, Tentakelfabrik | |||
| * @license http://opensource.org/licenses/MIT The MIT License | |||
| * @link https://gitea.tentakelfabrik.de/Tentakelfabrik/super-gear-directus | |||
| * | |||
| */ | |||
| class PostController extends DirectusControllerAbstract | |||
| { | |||
| /** | |||
| * get single page from slug | |||
| * | |||
| * | |||
| * @param string $slug | |||
| */ | |||
| public function getAction($slug) | |||
| { | |||
| $repository = new PostRepository(); | |||
| $post = $repository->findOneBySlug($slug); | |||
| if (count($post['data']) === 0) { | |||
| $this->app->redirect('/404'); | |||
| } else { | |||
| $this->render($post); | |||
| } | |||
| } | |||
| } | |||
| @ -1,51 +0,0 @@ | |||
| <?php | |||
| namespace App\Repositories; | |||
| use Exception; | |||
| /** | |||
| * Manager Class to create Repository Objects that | |||
| * are located in App\Repositories\ | |||
| * | |||
| * | |||
| * @author Björn Hase, Tentakelfabrik | |||
| * @license http://opensource.org/licenses/MIT The MIT License | |||
| * @link https://gitea.tentakelfabrik.de/Tentakelfabrik/super-gear-directus | |||
| * | |||
| */ | |||
| class Manager | |||
| { | |||
| /** | |||
| * naming of Repository | |||
| * @var string | |||
| */ | |||
| const NAMESPACE = 'App\Repositories\\'; | |||
| /** | |||
| * naming of Repository | |||
| * @var string | |||
| */ | |||
| const REPOSITORY_SUFFIX = 'Repository'; | |||
| /** | |||
| * getting repository object | |||
| * | |||
| * @param string $repositoryClass | |||
| * @return AbstractRepository | |||
| */ | |||
| public static function get($repositoryName) | |||
| { | |||
| $repositoryClass = self::NAMESPACE.$repositoryName.self::REPOSITORY_SUFFIX; | |||
| if (!class_exists($repositoryClass)) { | |||
| throw new Exception('Repository Class '.$repositoryClass.' not exists!'); | |||
| } | |||
| // create respository object | |||
| $repository = new $repositoryClass(); | |||
| return $repository; | |||
| } | |||
| } | |||
| @ -0,0 +1,83 @@ | |||
| <?php | |||
| namespace App\Repositories; | |||
| use App\Repositories\RepositoryAbstract; | |||
| /** | |||
| * request pages items from directus | |||
| * | |||
| * @author Björn Hase, Tentakelfabrik | |||
| * @license http://opensource.org/licenses/MIT The MIT License | |||
| * @link https://gitea.tentakelfabrik.de/Tentakelfabrik/super-gear-directus | |||
| * | |||
| */ | |||
| class PostRepository extends RepositoryAbstract | |||
| { | |||
| /** endpoint */ | |||
| protected $endpoint = 'posts'; | |||
| /** | |||
| * | |||
| */ | |||
| public function find($limit = 20) | |||
| { | |||
| return $this->queryBuilder | |||
| ->fields([ | |||
| 'title', | |||
| 'slug', | |||
| 'lead', | |||
| 'content', | |||
| 'view', | |||
| 'date_created', | |||
| 'published_at', | |||
| 'media_teaser.id', | |||
| 'media_teaser.description' | |||
| ]) | |||
| ->aliases('template', 'view') | |||
| ->filter([ | |||
| 'status' => 'published', | |||
| 'published_at' => [ | |||
| '_nnull' => 'true' | |||
| ] | |||
| ]) | |||
| ->sort(['published_at']) | |||
| ->find(); | |||
| } | |||
| /** | |||
| * find single page with a slug, | |||
| * page must be published | |||
| * | |||
| * @param string $slug | |||
| * @return array | |||
| */ | |||
| public function findOneBySlug($slug) | |||
| { | |||
| return $this->queryBuilder | |||
| ->fields([ | |||
| 'title', | |||
| 'slug', | |||
| 'lead', | |||
| 'content', | |||
| 'view', | |||
| 'meta', | |||
| 'date_created', | |||
| 'published_at', | |||
| 'media_teaser.id', | |||
| 'media_teaser.description', | |||
| 'media_hero.id', | |||
| 'media_hero.description', | |||
| ]) | |||
| ->aliases('template', 'view') | |||
| ->filter([ | |||
| 'status' => 'published', | |||
| 'published_at' => [ | |||
| '_nnull' => 'true' | |||
| ], | |||
| 'slug' => $slug | |||
| ]) | |||
| ->findOne(); | |||
| } | |||
| } | |||
| @ -0,0 +1,53 @@ | |||
| @extends('layout') | |||
| {{-- pretend duplicate content --}} | |||
| @push('head') | |||
| <meta name="robots" content="noindex,follow" /> | |||
| @endpush | |||
| {{-- inject helper for content & repositories --}} | |||
| @inject('markdownHelper', 'App\Helpers\MarkdownHelper') | |||
| @inject('postRepository', 'App\Repositories\PostRepository') | |||
| @php | |||
| $posts = $postRepository->find(); | |||
| @endphp | |||
| @section('content') | |||
| <h1> | |||
| {{ $page['data']['title'] }} | |||
| </h1> | |||
| <div class="content"> | |||
| {!! $markdownHelper->parse($page['data']['content']) !!} | |||
| </div> | |||
| @if (count($posts) > 0) | |||
| @foreach($posts['data'] as $post) | |||
| <a class="post" href="/blog/{{ $post['slug'] }}"> | |||
| <header class="post__header"> | |||
| <h2 class="post__title"> | |||
| {{ $post['title'] }} | |||
| </h2> | |||
| @include('partials.date', ['post' => $post]) | |||
| @include('partials.readtime', ['post' => $post]) | |||
| @if (isset($post['media_teaser']['id'])) | |||
| <div class="post__teaser"> | |||
| <img src="{{ assetsUrl($post['media_teaser']['id']) }}" alt="{{ $post['media_teaser']['description'] }}" /> | |||
| </div> | |||
| @endif | |||
| </header> | |||
| <div class="content post__lead"> | |||
| {!! $markdownHelper->parse($post['lead']) !!} | |||
| </div> | |||
| </div> | |||
| @endforeach | |||
| @else | |||
| <div class="post"> | |||
| <p> | |||
| Nothing! | |||
| </p> | |||
| </div> | |||
| @endif | |||
| @endsection | |||
| @ -0,0 +1,5 @@ | |||
| <div class="post__date"> | |||
| <time datetime="{{ $post['published_at'] }}"> | |||
| {{ Carbon\Carbon::parse($post['published_at'])->diffForHumans() }} | |||
| </time> | |||
| </div> | |||
| @ -0,0 +1,10 @@ | |||
| @php | |||
| $content = $post['lead'].$post['content']; | |||
| $readtime = (new \Mtownsend\ReadTime\ReadTime($content))->timeOnly(true)->setTranslation([ | |||
| 'minute' => '' | |||
| ])->get(); | |||
| @endphp | |||
| <div class="post__readtime"> | |||
| Reading time {{ $readtime }} Minutes | |||
| </div> | |||
| @ -0,0 +1,17 @@ | |||
| @extends('layout') | |||
| @inject('markdownHelper', 'App\Helpers\MarkdownHelper') | |||
| @section('content') | |||
| <h1> | |||
| {{ $page['data']['title'] }} | |||
| </h1> | |||
| <div class="content content--lead"> | |||
| {!! $markdownHelper->parse($page['data']['lead']) !!} | |||
| </div> | |||
| <div class="content"> | |||
| {!! $markdownHelper->parse($page['data']['content']) !!} | |||
| </div> | |||
| @endsection | |||
| @ -0,0 +1,38 @@ | |||
| @inject('markdownHelper', 'App\Helpers\MarkdownHelper') | |||
| @php | |||
| if (isset($_SERVER['HTTPS'])) { | |||
| $http = 'https'; | |||
| } else { | |||
| $http = 'http'; | |||
| } | |||
| $base_url = $http.'://'.$_SERVER['SERVER_NAME']; | |||
| @endphp | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> | |||
| <channel> | |||
| <title>{{ $site['data']['title'] }}</title> | |||
| <atom:link href="{{ $base_url }}/feed" rel="self" type="application/rss+xml" /> | |||
| <link>{{ $base_url }}/blog</link> | |||
| <description>{{ $site['data']['description'] }}</description> | |||
| <lastBuildDate>{{ date(DATE_RSS) }}</lastBuildDate> | |||
| <language>{{ $_ENV['APP_LOCALE'] }}-{{ strtoupper($_ENV['APP_LOCALE']) }}</language> | |||
| @foreach($posts['data'] as $post) | |||
| <item> | |||
| <title>{{ $post['title'] }}</title> | |||
| <link>{{ $base_url.'/blog/'.$post['slug'] }}</link> | |||
| <pubDate>{{ date(DATE_RSS, strtotime($post['published_at'])) }}</pubDate> | |||
| <description> | |||
| <![CDATA[ | |||
| {!! $markdownHelper->parse($post['lead']) !!} | |||
| {!! $markdownHelper->parse($post['content']) !!} | |||
| ]]> | |||
| </description> | |||
| <guid isPermaLink="false">{{ $post['slug'] }}</guid> | |||
| </item> | |||
| @endforeach | |||
| </channel> | |||
| </rss> | |||