Add basic language support

This commit is contained in:
Giuseppe Criscione 2019-04-14 16:39:42 +02:00
parent 024e08648e
commit 104ab82e85
7 changed files with 109 additions and 39 deletions

View File

@ -3,6 +3,7 @@
namespace Formwork\Core;
use Formwork\Utils\FileSystem;
use Formwork\Utils\HTTPRequest;
use LogicException;
abstract class AbstractPage
@ -28,13 +29,6 @@ abstract class AbstractPage
*/
protected $route;
/**
* Page URI
*
* @var string
*/
protected $uri;
/**
* Page data
*
@ -66,16 +60,21 @@ abstract class AbstractPage
/**
* Return a URI relative to page
*
* @param string $route
* @param string $path
* @param bool $includeLanguage
*
* @return string
*/
public function uri($route = null)
public function uri($path = '', $includeLanguage = true)
{
if (is_null($route)) {
return $this->uri;
$base = HTTPRequest::root();
if ($includeLanguage) {
$language = Formwork::instance()->language();
if (!is_null($language) && Formwork::instance()->defaultLanguage() !== $language) {
$base .= $language . '/';
}
}
return $this->uri . ltrim($route, '/');
return $base . ltrim($this->route, '/') . ltrim($path, '/');
}
/**

View File

@ -35,6 +35,27 @@ class Formwork
*/
protected $options = array();
/**
* Current request URI
*
* @var string
*/
protected $request;
/**
* Default language code
*
* @var string
*/
protected $defaultLanguage;
/**
* Current language code
*
* @var string
*/
protected $language;
/**
* Site instance
*
@ -91,11 +112,15 @@ class Formwork
date_default_timezone_set($this->option('date.timezone'));
$this->request = Uri::removeQuery(HTTPRequest::uri());
$this->loadLanguages();
$this->router = new Router($this->request);
$siteConfig = YAML::parseFile(CONFIG_PATH . 'site.yml');
$this->site = new Site($siteConfig);
$this->router = new Router(Uri::removeQuery(HTTPRequest::uri()));
if ($this->option('cache.enabled')) {
$this->cache = new SiteCache($this->option('cache.path'), $this->option('cache.time'));
$this->cacheKey = Uri::normalize(HTTPRequest::uri());
@ -192,6 +217,23 @@ class Formwork
return array_key_exists($option, $this->options) ? $this->options[$option] : $default;
}
/**
* Load language from request
*/
protected function loadLanguages()
{
if (!empty($languages = (array) $this->option('languages'))) {
$this->defaultLanguage = $this->option('languages.default', $languages[0]);
if (preg_match('~^/(' . implode('|', $languages) . ')/~i', $this->request, $matches)) {
list($match, $language) = $matches;
$this->language = $language;
$this->request = '/' . substr($this->request, strlen($match));
} else {
$this->language = $this->defaultLanguage;
}
}
}
/**
* Get default route
*

View File

@ -6,7 +6,6 @@ use Formwork\Files\Files;
use Formwork\Parsers\ParsedownExtension as Parsedown;
use Formwork\Parsers\YAML;
use Formwork\Utils\FileSystem;
use Formwork\Utils\HTTPRequest;
use Formwork\Utils\Uri;
use RuntimeException;
@ -61,6 +60,20 @@ class Page extends AbstractPage
*/
protected $slug;
/**
* Page language
*
* @var string
*/
protected $language;
/**
* Available page languages
*
* @var array
*/
protected $availableLanguages = array();
/**
* Page filename
*
@ -148,9 +161,10 @@ class Page extends AbstractPage
/**
* Create a new Page instance
*
* @param string $path
* @param string $path
* @param string|null $language
*/
public function __construct($path)
public function __construct($path, $language = null)
{
if (is_null(static::$contentParser)) {
static::$contentParser = new Parsedown();
@ -158,9 +172,9 @@ class Page extends AbstractPage
$this->path = FileSystem::normalize($path);
$this->relativePath = substr($this->path, strlen(Formwork::instance()->option('content.path')) - 1);
$this->route = Uri::normalize(preg_replace('~/(\d+-)~', '/', strtr($this->relativePath, DS, '/')));
$this->uri = HTTPRequest::root() . ltrim($this->route, '/');
$this->id = basename($this->path);
$this->slug = basename($this->route);
$this->language = $language ?: Formwork::instance()->language();
$this->loadFiles();
if (!$this->isEmpty()) {
$this->parse();
@ -192,7 +206,7 @@ class Page extends AbstractPage
*/
public function reload()
{
$vars = array('uri', 'filename', 'template', 'parents', 'children', 'descendants', 'siblings');
$vars = array('filename', 'template', 'parents', 'children', 'descendants', 'siblings');
foreach ($vars as $var) {
$this->$var = null;
}
@ -415,17 +429,44 @@ class Page extends AbstractPage
*/
protected function loadFiles()
{
$contentFiles = array();
$files = array();
foreach (FileSystem::listFiles($this->path) as $file) {
$name = FileSystem::name($file);
$extension = '.' . FileSystem::extension($file);
if (is_null($this->filename) && Formwork::instance()->site()->hasTemplate($name)) {
$this->filename = $file;
$this->template = new Template($name);
if ($extension === Formwork::instance()->option('content.extension')) {
$language = null;
if (preg_match('/([a-z0-9]+)\.([a-z]+)/', $name, $matches)) {
// Parse double extension
list($match, $name, $language) = $matches;
}
if (Formwork::instance()->site()->hasTemplate($name)) {
$contentFiles[$language] = array(
'filename' => $file,
'template' => $name
);
if (!is_null($language) && !in_array($language, $this->availableLanguages)) {
$this->availableLanguages[] = $language;
}
}
} elseif (in_array($extension, Formwork::instance()->option('files.allowed_extensions'), true)) {
$files[] = $file;
}
}
// Get correct content file based on requested language
ksort($contentFiles);
$key = isset($contentFiles[$this->language]) ? $this->language : array_keys($contentFiles)[0];
// Set actual language
if ($this->language !== $key) {
$this->language = $key ?: null;
}
$this->filename = $contentFiles[$key]['filename'];
$this->template = new Template($contentFiles[$key]['template']);
$this->files = new Files($files, $this->path);
}

View File

@ -4,7 +4,6 @@ namespace Formwork\Core;
use Formwork\Utils\FileSystem;
use Formwork\Utils\Header;
use Formwork\Utils\HTTPRequest;
class Site extends AbstractPage
{
@ -39,7 +38,6 @@ class Site extends AbstractPage
$this->path = Formwork::instance()->option('content.path');
$this->relativePath = DS;
$this->route = '/';
$this->uri = HTTPRequest::root();
$this->data = array_merge($this->defaults(), $data);
$this->loadTemplates();
}

View File

@ -193,7 +193,7 @@ class Template
}
return $this->assets = new Assets(
$this->path . 'assets' . DS,
Formwork::instance()->site()->uri('/templates/assets/')
Formwork::instance()->site()->uri('/templates/assets/', false)
);
}

View File

@ -2,7 +2,9 @@
namespace Formwork\Files;
use Formwork\Core\Formwork;
use Formwork\Utils\FileSystem;
use Formwork\Utils\HTTPRequest;
use Formwork\Utils\MimeType;
use Formwork\Utils\Str;
use Formwork\Utils\Uri;
@ -71,22 +73,10 @@ class File
$this->extension = FileSystem::extension($path);
$this->mimeType = FileSystem::mimeType($path);
$this->type = $this->type();
$this->uri = Uri::resolveRelativeUri($this->name, HTTPRequest::root() . ltrim(Formwork::instance()->request(), '/'));
$this->size = FileSystem::size($path);
}
/**
* Get file uri
*
* @return string|null
*/
public function uri()
{
if (!is_null($this->uri)) {
return $this->uri;
}
return $this->uri = Uri::resolveRelativeUri($this->name, Uri::relativePath());
}
/**
* Get file type
*

View File

@ -38,7 +38,7 @@ class ParsedownExtension extends ParsedownExtra
if (in_array(Uri::scheme($href), array(null, 'http', 'https'), true)) {
if (empty(Uri::host($href)) && $href[0] !== '#') {
$relativeUri = Uri::resolveRelativeUri($href, $this->page->route());
$href = Formwork::instance()->site()->uri($relativeUri);
$href = Formwork::instance()->site()->uri($relativeUri, false);
}
}
return $link;