@ -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> |