From 104ab82e855cdb2e00e3c45ca707fe845e801fc4 Mon Sep 17 00:00:00 2001 From: Giuseppe Criscione Date: Sun, 14 Apr 2019 16:39:42 +0200 Subject: [PATCH] Add basic language support --- formwork/Core/AbstractPage.php | 23 +++++----- formwork/Core/Formwork.php | 46 +++++++++++++++++++- formwork/Core/Page.php | 57 +++++++++++++++++++++---- formwork/Core/Site.php | 2 - formwork/Core/Template.php | 2 +- formwork/Files/File.php | 16 ++----- formwork/Parsers/ParsedownExtension.php | 2 +- 7 files changed, 109 insertions(+), 39 deletions(-) diff --git a/formwork/Core/AbstractPage.php b/formwork/Core/AbstractPage.php index 18e24c8b..395b7c5d 100644 --- a/formwork/Core/AbstractPage.php +++ b/formwork/Core/AbstractPage.php @@ -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, '/'); } /** diff --git a/formwork/Core/Formwork.php b/formwork/Core/Formwork.php index 0763dd3c..1beb5e52 100755 --- a/formwork/Core/Formwork.php +++ b/formwork/Core/Formwork.php @@ -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 * diff --git a/formwork/Core/Page.php b/formwork/Core/Page.php index 528ef222..ca8bf38d 100755 --- a/formwork/Core/Page.php +++ b/formwork/Core/Page.php @@ -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); } diff --git a/formwork/Core/Site.php b/formwork/Core/Site.php index 312da0d4..c1656942 100755 --- a/formwork/Core/Site.php +++ b/formwork/Core/Site.php @@ -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(); } diff --git a/formwork/Core/Template.php b/formwork/Core/Template.php index 03adb746..15ffbcc3 100755 --- a/formwork/Core/Template.php +++ b/formwork/Core/Template.php @@ -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) ); } diff --git a/formwork/Files/File.php b/formwork/Files/File.php index 5e0bcea4..cb574a35 100755 --- a/formwork/Files/File.php +++ b/formwork/Files/File.php @@ -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 * diff --git a/formwork/Parsers/ParsedownExtension.php b/formwork/Parsers/ParsedownExtension.php index 502edb51..a8a6c44d 100644 --- a/formwork/Parsers/ParsedownExtension.php +++ b/formwork/Parsers/ParsedownExtension.php @@ -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;