Skip to content

Commit

Permalink
Merge pull request #9 from locomotivemtl/feature-web-template
Browse files Browse the repository at this point in the history
Created an abstract template for web pages (display metatags, manage translations)
  • Loading branch information
dominiclord authored Sep 16, 2019
2 parents 4f52ae5 + 784cb69 commit 6ad7fd5
Show file tree
Hide file tree
Showing 9 changed files with 1,261 additions and 1 deletion.
521 changes: 521 additions & 0 deletions src/Charcoal/Cms/AbstractWebTemplate.php

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/Charcoal/Cms/MetatagInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
*/
interface MetatagInterface
{
const DEFAULT_OPENGRAPH_TYPE = 'website';

/**
* @return string
*/
Expand Down
9 changes: 8 additions & 1 deletion src/Charcoal/Cms/Route/GenericRoute.php
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,14 @@ protected function loadObjectRouteFromPath()
// Slug can be duplicated by adding the front "/" to it hence the order by last_modification_date
$route = $this->createRouteObject();
$route->loadFromQuery(
'SELECT * FROM `'.$route->source()->table().'` WHERE (`slug` = :route1 OR `slug` = :route2) AND `lang` = :lang ORDER BY last_modification_date DESC LIMIT 1',
sprintf(
'
SELECT * FROM `%s`
WHERE (`slug` = :route1 OR `slug` = :route2)
AND `lang` = :lang
ORDER BY last_modification_date DESC LIMIT 1',
$route->source()->table()
),
[
'route1' => '/'.$this->path(),
'route2' => $this->path(),
Expand Down
241 changes: 241 additions & 0 deletions src/Charcoal/Cms/Support/ContextualTemplateTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
<?php

namespace Charcoal\Cms\Support;

use InvalidArgumentException;

// From 'psr/http-message'
use Psr\Http\Message\UriInterface;

// From 'charcoal-core'
use Charcoal\Model\Model;
use Charcoal\Model\ModelInterface;

/**
* Additional utilities for the routing.
*/
trait ContextualTemplateTrait
{
/**
* The current rendering / data context.
*
* @var ModelInterface|null
*/
protected $contextObject;

/**
* The route group path (base URI).
*
* @var string|null
*/
protected $routeGroup;

/**
* The route endpoint path (path URI).
*
* @var string|null
*/
protected $routeEndpoint;

/**
* Track the state of context creation.
*
* @var boolean
*/
protected $isCreatingContext = false;

/**
* The class name of the section model.
*
* A fully-qualified PHP namespace. Used for the model factory.
*
* @var string
*/
protected $genericContextClass = Model::class;

/**
* Set the class name of the generic context model.
*
* @param string $className The class name of the section model.
* @throws InvalidArgumentException If the class name is not a string.
* @return AbstractPropertyDisplay Chainable
*/
public function setGenericContextClass($className)
{
if (!is_string($className)) {
throw new InvalidArgumentException(
'Generic context class name must be a string.'
);
}

$this->genericContextClass = $className;

return $this;
}

/**
* Retrieve the class name of the generic context model.
*
* @return string
*/
public function genericContextClass()
{
return $this->genericContextClass;
}

/**
* Set the current renderable object relative to the context.
*
* @param ModelInterface $context The context / view to render the template with.
* @return self
*/
public function setContextObject(ModelInterface $context)
{
$this->contextObject = $context;

return $this;
}

/**
* Retrieve the current object relative to the context.
*
* This method is meant to be reimplemented in a child template controller
* to return the resolved object that the module considers "the context".
*
* @return ModelInterface|null
*/
public function contextObject()
{
if ($this->contextObject === null) {
$this->contextObject = $this->createGenericContext();
}

return $this->contextObject;
}

/**
* Create a generic object relative to the context.
*
* @return ModelInterface|null
*/
protected function createGenericContext()
{
if ($this->isCreatingContext) {
return null;
}

$this->isCreatingContext = true;

$obj = $this->modelFactory()->create($this->genericContextClass());

$baseUrl = $this->baseUrl();
if ($this->routeEndpoint) {
$endpoint = $this->translator()->translation($this->routeEndpoint);
foreach ($this->translator()->availableLocales() as $lang) {
$uri = $baseUrl->withPath($endpoint[$lang]);

if ($this->routeGroup) {
$uri = $uri->withBasePath($this->routeGroup[$lang]);
}

$base = $uri->getBasePath();
$path = $uri->getPath();
$path = $base.'/'.ltrim($path, '/');

$endpoint[$lang] = $path;
}
} else {
$endpoint = null;
}

$obj['url'] = $endpoint;
$obj['title'] = $this->title();

$this->isCreatingContext = false;

return $obj;
}

/**
* Retrieve the current URI of the context.
*
* @return UriInterface|string|null
*/
public function currentUrl()
{
$context = $this->contextObject();

if ($context && isset($context['url'])) {
return $context['url'];
}

return null;
}

/**
* Append a path to the base URI.
*
* @param string $path The base path.
* @return self
*/
public function setRouteGroup($path)
{
$group = $this->translator()->translation($path);

foreach ($this->translator()->availableLocales() as $lang) {
$group[$lang] = trim($group[$lang], '/');
}

$this->routeGroup = $group;

return $this;
}

/**
* Append a path to the URI.
*
* @param string $path The main path.
* @return self
*/
public function setRouteEndpoint($path)
{
$endpoint = $this->translator()->translation($path);

foreach ($this->translator()->availableLocales() as $lang) {
$endpoint[$lang] = trim($endpoint[$lang], '/');
}

$this->routeEndpoint = $endpoint;

return $this;
}

/**
* Retrieve the base URI of the project.
*
* @return UriInterface|null
*/
abstract public function baseUrl();

/**
* Retrieve the title of the page (from the context).
*
* @return string
*/
abstract public function title();

/**
* Retrieve the translator service.
*
* @see \Charcoal\Translator\TranslatorAwareTrait
* @return \Charcoal\Translator\Translator
*/
abstract protected function translator();

/**
* Retrieve the object model factory.
*
* @return \Charcoal\Factory\FactoryInterface
*/
abstract public function modelFactory();
}
Loading

0 comments on commit 6ad7fd5

Please sign in to comment.