@ -1,4 +1,5 @@ | |||||
APP_DEBUG=false | APP_DEBUG=false | ||||
APP_LOCALE=en | |||||
DIRECTUS_API_URL= | DIRECTUS_API_URL= | ||||
DIRECTUS_API_TOKEN= | 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> |