Skip to content
This repository has been archived by the owner on Dec 27, 2018. It is now read-only.

Commit

Permalink
[WIP] Multi-themes support (#377)
Browse files Browse the repository at this point in the history
```yaml
theme:
- a-theme
- hyde
```
- For any template, PHPoole will look first in `layouts/` and then in `themes/a-theme/layouts/`, and then in `themes/hyde/layouts/`, and lastly in `res/layouts` (internal).
- Static files (in `static/`) are recursively copied from each theme.
- Config file (`phpoole.yml`) is imported from each theme.
  • Loading branch information
ArnaudLigny committed Nov 14, 2018
1 parent 80a5944 commit 5713e1b
Show file tree
Hide file tree
Showing 28 changed files with 390 additions and 213 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.9.1
2.10.0
15 changes: 12 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
{
"name": "phpoole/library",
"description": "An intuitive PHP library to create a static website.",
"keywords": ["static", "website", "generator", "flat file", "markdown", "twig"],
"keywords": [
"static",
"website",
"generator",
"flat file",
"markdown",
"twig"
],
"homepage": "https://github.com/PHPoole/library",
"license": "MIT",
"type": "library",
Expand Down Expand Up @@ -35,7 +42,7 @@
"phpunit/phpunit": "7.2.7"
},
"autoload": {
"psr-4" : {
"psr-4": {
"PHPoole\\": "src"
}
},
Expand Down Expand Up @@ -63,6 +70,8 @@
"php coveralls.phar -v"
],
"api-docs-install": "curl -O http://get.sensiolabs.org/sami.phar",
"api-docs-build": "php sami.phar update sami.php"
"api-docs-build": "php sami.phar update sami.php",
"post-install-cmd": "cd tests/fixtures/website;composer install;",
"post-update-cmd": "cd tests/fixtures/website;composer update;"
}
}
138 changes: 98 additions & 40 deletions src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,17 @@ public function __construct($config = null)
{
$data = new Data(self::$defaultData);

if ($config instanceof self) {
$data->importData($config->getAll());
} elseif (is_array($config)) {
$data->import($config);
if ($config) {
if ($config instanceof self) {
$data->importData($config->getAll());
} elseif (is_array($config)) {
$data->import($config);
}
}

// Apply environment variables
/**
* Apply environment variables.
*/
$applyEnv = function ($array) use ($data) {
$iterator = new \RecursiveIteratorIterator(
new \RecursiveArrayIterator($array),
Expand All @@ -159,6 +163,24 @@ public function __construct($config = null)
$this->setFromData($data);
}

/**
* Import array config to current config.
*
* @param array $config
*
* @return $this
*/
public function import($config)
{
if (is_array($config)) {
$data = $this->getAll();
$origin = $data->export();
$data->import($config);
$data->import($origin);
$this->setFromData($data);
}
}

/**
* Set config data.
*
Expand Down Expand Up @@ -272,35 +294,13 @@ public function getDestinationDir()
return $this->destinationDir;
}

/**
* Is config has a valid theme?
*
* @throws Exception
*
* @return bool
*/
public function hasTheme()
{
if ($this->get('theme')) {
if (!Util::getFS()->exists($this->getThemePath($this->get('theme')))) {
throw new Exception(sprintf(
"Theme directory '%s/%s/layouts' not found!",
$this->getThemesPath(),
$this->get('theme')
));
}

return true;
}

return false;
}

/**
* Path helpers.
*/

/**
* Return content directory path.
*
* @return string
*/
public function getContentPath()
Expand All @@ -309,6 +309,8 @@ public function getContentPath()
}

/**
* Return templates directory path.
*
* @return string
*/
public function getLayoutsPath()
Expand All @@ -317,6 +319,18 @@ public function getLayoutsPath()
}

/**
* Return themes directory path.
*
* @return string
*/
public function getThemesPath()
{
return $this->getSourceDir().'/'.$this->get('themes.dir');
}

/**
* Return internal templates directory path.
*
* @return string
*/
public function getInternalLayoutsPath()
Expand All @@ -325,37 +339,81 @@ public function getInternalLayoutsPath()
}

/**
* Return output directory path.
*
* @return string
*/
public function getThemesPath()
public function getOutputPath()
{
return $this->getSourceDir().'/'.$this->get('themes.dir');
return $this->getSourceDir().'/'.$this->get('output.dir');
}

/**
* @param string $theme
* @param string $dir
* Return static files directory path.
*
* @return string
*/
public function getThemePath($theme, $dir = 'layouts')
public function getStaticPath()
{
return $this->getSourceDir().'/'.$this->get('themes.dir').'/'.$theme.'/'.$dir;
return $this->getSourceDir().'/'.$this->get('static.dir');
}

/**
* @return string
* Themes helpers.
*/
public function getOutputPath()

/**
* Return theme(s).
*
* @return array|null
*/
public function getTheme()
{
return $this->getSourceDir().'/'.$this->get('output.dir');
if ($themes = $this->get('theme')) {
if (is_array($themes)) {
return $themes;
}

return [$themes];
}
}

/**
* Has a (valid) theme(s)?
*
* @throws Exception
*
* @return bool
*/
public function hasTheme()
{
if ($themes = $this->getTheme()) {
foreach ($themes as $theme) {
if (!Util::getFS()->exists($this->getThemeDirPath($theme, 'layouts'))) {
throw new Exception(sprintf(
"Theme directory '%s/%s/layouts' not found!",
$this->getThemesPath(),
$theme
));
}
}

return true;
}

return false;
}

/**
* Return the path of a specific theme's directory.
*
* @param string $theme
* @param string $dir
*
* @return string
*/
public function getStaticPath()
public function getThemeDirPath($theme, $dir = 'layouts')
{
return $this->getSourceDir().'/'.$this->get('static.dir');
return $this->getThemesPath().'/'.$theme.'/'.$dir;
}
}
8 changes: 6 additions & 2 deletions src/PHPoole.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class PHPoole
* @see build()
*/
protected $steps = [
'PHPoole\Step\ImportConfig',
'PHPoole\Step\LocateContent',
'PHPoole\Step\CreatePages',
'PHPoole\Step\ConvertPages',
Expand Down Expand Up @@ -101,8 +102,9 @@ class PHPoole
*/
public function __construct($config = null, \Closure $messageCallback = null)
{
$this->setConfig($config);
$this->config->setSourceDir(null)->setDestinationDir(null);
$this->setConfig($config)
->setSourceDir(null)
->setDestinationDir(null);
$this->setMessageCallback($messageCallback);
}

Expand Down Expand Up @@ -229,6 +231,7 @@ public function setMessageCallback($messageCallback = null)
if ($messageCallback === null) {
$messageCallback = function ($code, $message = '', $itemsCount = 0, $itemsMax = 0) {
switch ($code) {
case 'CONFIG':
case 'LOCATE':
case 'CREATE':
case 'CONVERT':
Expand All @@ -241,6 +244,7 @@ public function setMessageCallback($messageCallback = null)
$log = sprintf("%s\n", $message);
$this->addLog($log);
break;
case 'CONFIG_PROGRESS':
case 'LOCATE_PROGRESS':
case 'CREATE_PROGRESS':
case 'CONVERT_PROGRESS':
Expand Down
36 changes: 20 additions & 16 deletions src/Renderer/Layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,20 @@ public function finder(Page $page, Config $config)

// take the first available layout
foreach ($layouts as $layout) {
// is it in layouts dir?
// is it in layouts/ dir?
if (Util::getFS()->exists($config->getLayoutsPath().'/'.$layout)) {
return $layout;
}
// is it in theme dir?
// is it in <theme>/layouts/ dir?
if ($config->hasTheme()) {
if (Util::getFS()->exists($config->getThemePath($config->get('theme')).'/'.$layout)) {
return $layout;
$themes = $config->getTheme();
foreach ($themes as $theme) {
if (Util::getFS()->exists($config->getThemeDirPath($theme, 'layouts').'/'.$layout)) {
return $layout;
}
}
}
// is it in internal dir?
// is it in res/layouts/ dir?
if (Util::getFS()->exists($config->getInternalLayoutsPath().'/'.$layout)) {
return $layout;
}
Expand Down Expand Up @@ -120,33 +123,34 @@ protected static function fallback(Page $page)
break;
default:
$layouts = [
// '$section/page.html.twig',
// '$section/$layout.twig',
// '$layout.twig',
// '$section/page.html.twig',
// 'page.html.twig',
'_default/page.html.twig',
];
$layouts = array_merge(
['page.html.twig'],
$layouts
);

if ($page->getSection()) {
$layouts = array_merge(
[sprintf('%s/page.html.twig', $page->getSection())],
$layouts
);
if ($page->getLayout()) {
$layouts = array_merge(
[sprintf('%s/%s.twig', $page->getSection(), $layout)],
$layouts
);
}
}
$layouts = array_merge(
['page.html.twig'],
$layouts
);
if ($page->getLayout()) {
$layouts = array_merge(
[sprintf('%s.twig', $layout)],
$layouts
);
if ($page->getSection()) {
$layouts = array_merge(
[sprintf('%s/%s.twig', $page->getSection(), $layout)],
$layouts
);
}
}
}

Expand Down
30 changes: 16 additions & 14 deletions src/Step/CopyStatic.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,25 @@ public function process()
$count = 0;

call_user_func_array($this->phpoole->getMessageCb(), ['COPY', 'Copying static files']);
// copy theme static dir if exists
// copy <theme>/static/ dir if exists
if ($this->phpoole->getConfig()->hasTheme()) {
$theme = $this->phpoole->getConfig()->get('theme');
$themeStaticDir = $this->phpoole->getConfig()->getThemePath($theme, 'static');
if (Util::getFS()->exists($themeStaticDir)) {
$finder = new Finder();
$finder->files()->in($themeStaticDir);
$count += $finder->count();
Util::getFS()->mirror(
$themeStaticDir,
$this->phpoole->getConfig()->getOutputPath(),
null,
['override' => true]
);
$themes = array_reverse($this->phpoole->getConfig()->getTheme());
foreach ($themes as $theme) {
$themeStaticDir = $this->phpoole->getConfig()->getThemeDirPath($theme, 'static');
if (Util::getFS()->exists($themeStaticDir)) {
$finder = new Finder();
$finder->files()->in($themeStaticDir);
$count += $finder->count();
Util::getFS()->mirror(
$themeStaticDir,
$this->phpoole->getConfig()->getOutputPath(),
null,
['override' => true]
);
}
}
}
// copy static dir if exists
// copy static/ dir if exists
$staticDir = $this->phpoole->getConfig()->getStaticPath();
if (Util::getFS()->exists($staticDir)) {
$finder = new Finder();
Expand Down

0 comments on commit 5713e1b

Please sign in to comment.