diff --git a/libs/BaseConfig.php b/libs/BaseConfig.php index 7a867dc..6e1ec4d 100644 --- a/libs/BaseConfig.php +++ b/libs/BaseConfig.php @@ -36,4 +36,19 @@ class BaseConfig extends ArrayObject } } } + + public function hasValue($key) + { + return array_key_exists($key, $this); + } + + public function getValue($key) + { + return $this[$key]; + } + + public function setValue($key, $value) + { + $this[$key] = $value; + } } diff --git a/libs/Config.php b/libs/Config.php index 31b5a22..560ea56 100644 --- a/libs/Config.php +++ b/libs/Config.php @@ -2,91 +2,96 @@ use Todaymade\Daux\Tree\Content; use Todaymade\Daux\Format\HTML\Config as HTMLConfig; +use Todaymade\Daux\Format\HTML\Theme as Theme; +use Todaymade\Daux\Format\Confluence\Config as ConfluenceConfig; class Config extends BaseConfig { - public function getTitle() - { - return $this['title']; + public function getTitle() { + return $this->getValue('title'); } - public function getCurrentPage() - { - return $this['current_page']; + public function hasAuthor(): bool { + return $this->hasValue('author'); } - public function setCurrentPage(Content $entry) - { - $this['current_page'] = $entry; + public function getAuthor() { + return $this->getValue('author'); } - public function getDocumentationDirectory() - { - return $this['docs_directory']; + public function hasTagline(): bool { + return $this->hasValue('tagline'); } - public function setDocumentationDirectory($documentationPath) - { - $this['docs_directory'] = $documentationPath; + public function getTagline() { + return $this->getValue('tagline'); } - public function getThemesDirectory() - { - return $this['themes_directory']; + public function getCurrentPage() { + return $this->getValue('current_page'); } - public function setThemesDirectory($directory) - { - $this['themes_directory'] = $directory; + public function setCurrentPage(Content $entry) { + $this->setValue('current_page', $entry); } - public function setThemesPath($themePath) - { - $this['themes_path'] = $themePath; + public function getDocumentationDirectory() { + return $this->getValue('docs_directory'); } - public function getThemesPath() - { - return $this['themes_path']; + public function getThemesDirectory() { + return $this->getValue('themes_directory'); } - public function setFormat($format) - { - $this['format'] = $format; + public function getThemesPath() { + return $this->getValue('themes_path'); } - public function getFormat() - { - return $this['format']; + public function getFormat() { + return $this->getValue('format'); } - public function hasTimezone() - { + public function hasTimezone(): bool { return isset($this['timezone']); } - public function getTimezone() - { - return $this['timezone']; + public function getTimezone() { + return $this->getValue('timezone'); } - public function isMultilanguage() - { - return array_key_exists('languages', $this) && !empty($this['languages']); + public function getTree() { + return $this->getValue('tree'); } - public function isLive() - { - return $this['mode'] == Daux::LIVE_MODE; + public function setTree($tree) { + $this->setValue('tree', $tree); } - public function isStatic() - { - return $this['mode'] == Daux::STATIC_MODE; + public function isMultilanguage(): bool { + return $this->hasValue('languages') && !empty($this->getValue('languages')); } - public function shouldInheritIndex() - { + public function getLanguages(): array { + return $this->getValue('languages'); + } + + public function getLanguage(): string { + return $this->getValue('language'); + } + + public function getMode() { + return $this->getValue('mode'); + } + + public function isLive() { + return $this->getValue('mode') == Daux::LIVE_MODE; + } + + public function isStatic() { + return $this->getValue('mode') == Daux::STATIC_MODE; + } + + public function shouldInheritIndex() { // As the global configuration is always present, we // need to test for the existence of the legacy value // first. Then use the current value. @@ -97,41 +102,43 @@ class Config extends BaseConfig return $this['html']['inherit_index']; } - public function setConfigurationOverrideFile($override_file) - { - $this['override_file'] = $override_file; + public function getIndexKey() { + return $this->getValue('mode') == Daux::STATIC_MODE ? 'index.html' : 'index'; } - public function getConfigurationOverrideFile() - { - if (array_key_exists('override_file', $this)) { - return $this['override_file']; - } - - return null; + public function getProcessor() { + return $this->getValue('processor'); } - public function getConfluenceConfiguration() - { - return $this['confluence']; + public function getConfluenceConfiguration(): ConfluenceConfig { + return new ConfluenceConfig($this->hasValue('confluence') ? $this->getValue('confluence') : []); } - public function getHTML() - { - return new HTMLConfig($this['html']); + public function getHTML(): HTMLConfig { + return new HTMLConfig($this->hasValue('html') ? $this->getValue('html') : []); } - public function canCache() - { - if (array_key_exists('cache', $this)) { - return $this['cache']; + public function getTheme(): ?Theme { + return $this->hasValue('theme') ? new Theme($this->getValue('theme')) : null; + } + + public function getValidContentExtensions() { + return $this->getValue('valid_content_extensions'); + } + + public function setValidContentExtensions(array $value) { + $this->setValue('valid_content_extensions', $value); + } + + public function canCache() { + if ($this->hasValue('cache')) { + return $this->getValue('cache'); } return false; } - public function getCacheKey() - { + public function getCacheKey() { $cloned = []; foreach ($this as $key => $value) { $cloned[$key] = ($value instanceof Entry) ? $value->dump() : $value; @@ -139,4 +146,105 @@ class Config extends BaseConfig return sha1(json_encode($cloned)); } + + public function hasTranslationKey($language, $key): bool { + return array_key_exists($language, $this['strings']) && array_key_exists($key, $this['strings'][$language]); + } + + public function getTranslationKey($language, $key) { + return $this['strings'][$language][$key]; + } + + public function hasImage(): bool { + return $this->hasValue('image'); + } + + public function getImage() { + return $this->getValue('image'); + } + + public function setImage($value) { + return $this->setValue('image', $value); + } + + public function getLocalBase() { + return $this->getValue('local_base'); + } + + public function getTemplates() { + return $this->getValue('templates'); + } + + public function getBaseUrl() { + return $this->getValue('base_url'); + } + + public function getBasePage() { + + if ($this->isLive()) { + $value = '//' . $this->getBaseUrl(); + if (!$this['live']['clean_urls']) { + $value .= 'index.php/'; + } + + return $value; + } + return $this->getBaseUrl(); + } + + public function hasEntryPage(): bool { + return $this->hasValue('entry_page') && !empty($this->getValue('entry_page')); + } + + public function getEntryPage() { + return $this->getValue('entry_page'); + } + + public function setEntryPage($value) { + return $this->setValue('entry_page', $value); + } + + public function hasRequest(): bool { + return $this->hasValue('request') && !empty($this->getValue('request')); + } + + public function getRequest() { + return $this->getValue('request'); + } + + public function setRequest($value) { + return $this->setValue('request', $value); + } + + public function getIndex() { + return $this->getValue('index'); + } + + public function setIndex($value) { + return $this->setValue('index', $value); + } + + public function hasProcessorInstance() { + return $this->hasValue('processor_instance'); + } + + public function getProcessorInstance() { + return $this->getValue('processor_instance'); + } + + public function setProcessorInstance($value) { + return $this->setValue('processor_instance', $value); + } + + public function getIgnore() { + return $this->getValue('ignore'); + } + + public function hasHost() { + return $this->hasValue('host'); + } + + public function getHost() { + return $this->getValue('host'); + } } diff --git a/libs/ConfigBuilder.php b/libs/ConfigBuilder.php new file mode 100644 index 0000000..7bc33dc --- /dev/null +++ b/libs/ConfigBuilder.php @@ -0,0 +1,288 @@ +config = new Config(); + $this->config['mode'] = $mode; + $this->config['local_base'] = dirname(__DIR__); + } + + static function fromFile($file): Config { + return unserialize(file_get_contents($file)); + } + + static function withMode($mode = Daux::STATIC_MODE): ConfigBuilder { + $builder = new ConfigBuilder($mode); + $builder->loadBaseConfiguration(); + return $builder; + } + + public function with(array $values): ConfigBuilder { + $this->config->merge($values); + return $this; + } + + private function setValue(&$array, $key, $value) { + if (is_null($key)) { + return $array = $value; + } + $keys = explode('.', $key); + while (count($keys) > 1) { + $key = array_shift($keys); + if (!isset($array[$key]) || !is_array($array[$key])) { + $array[$key] = []; + } + $array = &$array[$key]; + } + $array[array_shift($keys)] = $value; + return $array; + } + + public function withValues(array $values): ConfigBuilder { + foreach ($values as $value) { + $this->setValue($this->config, $value[0], $value[1]); + } + return $this; + } + + public function withDocumentationDirectory($dir): ConfigBuilder { + $this->config['docs_directory'] = $dir; + return $this; + } + + public function withValidContentExtensions(array $value): ConfigBuilder { + $this->config['valid_content_extensions'] = $value; + return $this; + } + + public function withThemesPath($themePath): ConfigBuilder { + $this->config['themes_path'] = $themePath; + return $this; + } + + public function withThemesDirectory($directory): ConfigBuilder { + $this->config['themes_directory'] = $directory; + return $this; + } + + public function withCache(bool $value): ConfigBuilder { + $this->config['cache'] = $value; + return $this; + } + + public function withFormat($format): ConfigBuilder { + $this->config['format'] = $format; + return $this; + } + + public function withConfigurationOverride($file): ConfigBuilder { + $this->configuration_override_file = $file; + return $this; + } + + public function withProcessor($value): ConfigBuilder { + $this->config['processor'] = $value; + return $this; + } + + public function withSearch($value): ConfigBuilder { + $this->config['html']['search'] = $value; + return $this; + } + + public function withConfluenceDelete($value): ConfigBuilder { + $this->config['confluence']['delete'] = $value; + return $this; + } + + function build(): Config { + $this->initializeConfiguration(); + + return $this->config; + } + + private function resolveThemeVariant() { + $theme = $this->config->getHTML()->getTheme(); + $themesPath = $this->config->getThemesPath() . DIRECTORY_SEPARATOR; + + // If theme directory exists, we're good with that + if (is_dir(realpath(($themesPath . $theme)))) { + return [$theme, '']; + } + + $themePieces = explode('-', $theme); + $variant = ''; + + // Do we have a variant or only a theme ? + if (count($themePieces) > 1) { + $variant = array_pop($themePieces); + $theme = implode('-', $themePieces); + } + + if (!is_dir(realpath($themesPath . $theme))) { + throw new \RuntimeException("Theme '{$theme}' not found"); + } + + return [$theme, $variant]; + } + + /** + * @param string $override_file + * @throws Exception + */ + private function initializeConfiguration() { + // Validate and set theme path + $docs_path = $this->normalizeDocumentationPath($this->config->getDocumentationDirectory()); + $this->config['docs_directory'] = $docs_path; + + // Read documentation overrides + $this->loadConfiguration($docs_path . DIRECTORY_SEPARATOR . 'config.json'); + + // Read command line overrides + $override_file = $this->getConfigurationOverride($this->configuration_override_file); + if ($override_file !== null) { + $this->loadConfiguration($override_file); + } + + // Validate and set theme path + $this->withThemesPath($this->normalizeThemePath($this->config->getThemesDirectory())); + + // Resolve variant once + $theme = $this->resolveThemeVariant(); + $this->config['html']['theme'] = $theme[0]; + $this->config['html']['theme-variant'] = $theme[1]; + + // Set a valid default timezone + if ($this->config->hasTimezone()) { + date_default_timezone_set($this->config->getTimezone()); + } elseif (!ini_get('date.timezone')) { + date_default_timezone_set('GMT'); + } + + // Text search would be too slow on live server + if ($this->config->isLive()) { + $this->config['html']['search'] = false; + } + } + + private function normalizeThemePath($path) { + $validPath = $this->findLocation($path, $this->config->getLocalBase(), 'dir'); + + if (!$validPath) { + throw new Exception('The Themes directory does not exist. Check the path again : ' . $path); + } + + return $validPath; + } + + private function normalizeDocumentationPath($path) { + $validPath = $this->findLocation($path, $this->config->getLocalBase(), 'dir'); + + if (!$validPath) { + throw new Exception('The Docs directory does not exist. Check the path again : ' . $path); + } + + return $validPath; + } + + /** + * Load and validate the global configuration + * + * @throws Exception + */ + private function loadBaseConfiguration() { + // Set the default configuration + $this->config->merge([ + 'docs_directory' => 'docs', + 'valid_content_extensions' => ['md', 'markdown'], + + //Paths and tree + 'templates' => 'templates', + + 'base_url' => '', + ]); + + // Load the global configuration + $this->loadConfiguration($this->config->getLocalBase() . DIRECTORY_SEPARATOR . 'global.json', false); + } + + /** + * @param string $config_file + * @param bool $optional + * @throws Exception + */ + private function loadConfiguration($config_file, $optional = true) { + if (!file_exists($config_file)) { + if ($optional) { + return; + } + + throw new Exception('The configuration file is missing. Check path : ' . $config_file); + } + + $config = json_decode(file_get_contents($config_file), true); + if (!isset($config)) { + throw new Exception('The configuration file "' . $config_file . '" is corrupt. Is your JSON well-formed ?'); + } + $this->config->merge($config); + } + + /** + * Get the file requested for configuration overrides + * + * @param string|null $path + * @return string|null the path to a file to load for configuration overrides + * @throws Exception + */ + private function getConfigurationOverride($path) { + $validPath = $this->findLocation($path, $this->config->getLocalBase(), 'file'); + + if ($validPath === null) { + return null; + } + + if (!$validPath) { + throw new Exception('The configuration override file does not exist. Check the path again : ' . $path); + } + + return $validPath; + } + + /** + * @param string|null $path + * @param string $basedir + * @param "dir"|"file" $type + * @return false|null|string + */ + private function findLocation($path, $basedir, $type) { + // If Path is explicitly null, it's useless to go further + if ($path == null) { + return null; + } + + // VFS, used only in tests + if (substr($path, 0, 6) == "vfs://") { + return $path; + } + + + // Check if it's relative to the current directory or an absolute path + if (DauxHelper::is($path, $type)) { + return DauxHelper::getAbsolutePath($path); + } + + // Check if it exists relative to Daux's root + $newPath = $basedir . DIRECTORY_SEPARATOR . $path; + if (DauxHelper::is($newPath, $type)) { + return $newPath; + } + + return false; + } +} \ No newline at end of file diff --git a/libs/Console/DauxCommand.php b/libs/Console/DauxCommand.php index b207e07..defe0f1 100644 --- a/libs/Console/DauxCommand.php +++ b/libs/Console/DauxCommand.php @@ -4,6 +4,7 @@ use Symfony\Component\Console\Command\Command as SymfonyCommand; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Todaymade\Daux\ConfigBuilder; use Todaymade\Daux\Daux; class DauxCommand extends SymfonyCommand @@ -12,78 +13,55 @@ class DauxCommand extends SymfonyCommand { $this ->addOption('configuration', 'c', InputOption::VALUE_REQUIRED, 'Configuration file') - ->addOption('value', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Set different configuration values') ->addOption('source', 's', InputOption::VALUE_REQUIRED, 'Where to take the documentation from') ->addOption('processor', 'p', InputOption::VALUE_REQUIRED, 'Manipulations on the tree') - ->addOption('no-cache', null, InputOption::VALUE_NONE, 'Disable Cache'); - - // HTML Format only - $this->addOption('themes', 't', InputOption::VALUE_REQUIRED, 'Set a different themes directory'); + ->addOption('no-cache', null, InputOption::VALUE_NONE, 'Disable Cache') + ->addOption('themes', 't', InputOption::VALUE_REQUIRED, 'Set a different themes directory (Used by HTML format only)') + ->addOption('value', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Set different configuration values'); } - private function setValue(&$array, $key, $value) + protected function prepareConfig($mode, InputInterface $input, OutputInterface $output): ConfigBuilder { - if (is_null($key)) { - return $array = $value; - } - $keys = explode('.', $key); - while (count($keys) > 1) { - $key = array_shift($keys); - if (!isset($array[$key]) || !is_array($array[$key])) { - $array[$key] = []; - } - $array = &$array[$key]; - } - $array[array_shift($keys)] = $value; - return $array; - } + $builder = ConfigBuilder::withMode($mode); - private function applyConfiguration(array $options, Daux $daux) - { - $values = array_map( - function($value) { - return array_map("trim", explode('=', $value)); - }, - $options - ); - - foreach ($values as $value) { - $this->setValue($daux->options, $value[0], $value[1]); - } - } - - protected function prepareDaux(InputInterface $input, OutputInterface $output) - { - $daux = new Daux(Daux::STATIC_MODE, $output); - - // Set the format if requested - if ($input->hasOption('format') && $input->getOption('format')) { - $daux->getParams()->setFormat($input->getOption('format')); + if ($input->getOption('configuration')) { + $builder->withConfigurationOverride($input->getOption('configuration')); } - // Set the source directory if ($input->getOption('source')) { - $daux->getParams()->setDocumentationDirectory($input->getOption('source')); + $builder->withDocumentationDirectory($input->getOption('source')); } - if ($input->getOption('themes')) { - $daux->getParams()->setThemesDirectory($input->getOption('themes')); - } - - $daux->initializeConfiguration($input->getOption('configuration')); - - if ($input->hasOption('delete') && $input->getOption('delete')) { - $daux->getParams()['confluence']['delete'] = true; - } - - if ($input->hasOption('value')) { - $this->applyConfiguration($input->getOption('value'), $daux); + if ($input->getOption('processor')) { + $builder->withProcessor($input->getOption('processor')); } if ($input->getOption('no-cache')) { - $daux->getParams()['cache'] = false; + $builder->withCache(false); } - return $daux; + if ($input->getOption('themes')) { + $builder->withThemesDirectory($input->getOption('themes')); + } + + if ($input->hasOption('value')) { + $values = array_map( + function($value) { + return array_map("trim", explode('=', $value)); + }, + $input->getOption('value') + ); + $builder->withValues($values); + } + + return $builder; + } + + protected function prepareProcessor(Daux $daux, $width) + { + $class = $daux->getProcessorClass(); + if (!empty($class)) { + $daux->setProcessor(new $class($daux, $output, $width)); + } } } diff --git a/libs/Console/Generate.php b/libs/Console/Generate.php index 3101bef..e1e8a65 100755 --- a/libs/Console/Generate.php +++ b/libs/Console/Generate.php @@ -7,6 +7,7 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Terminal; use Todaymade\Daux\Daux; +use Todaymade\Daux\ConfigBuilder; class Generate extends DauxCommand { @@ -29,6 +30,26 @@ class Generate extends DauxCommand ->addOption('search', null, InputOption::VALUE_NONE, 'Generate full text search'); } + protected function prepareConfig($mode, InputInterface $input, OutputInterface $output): ConfigBuilder + { + $builder = parent::prepareConfig($mode, $input, $output); + + // Set the format if requested + if ($input->hasOption('format') && $input->getOption('format')) { + $builder->withFormat($input->getOption('format')); + } + + if ($input->hasOption('delete') && $input->getOption('delete')) { + $builder->withConfluenceDelete(true); + } + + if ($input->hasOption('search')) { + $builder->withSearch($input->getOption('search')); + } + + return $builder; + } + protected function execute(InputInterface $input, OutputInterface $output) { // When used as a default command, @@ -42,12 +63,13 @@ class Generate extends DauxCommand $input = new ArgvInput($argv, $this->getDefinition()); } - $daux = $this->prepareDaux($input, $output); + $builder = $this->prepareConfig(Daux::STATIC_MODE, $input, $output); + $daux = new Daux($builder->build(), $output); $width = (new Terminal)->getWidth(); // Instiantiate the processor if one is defined - $this->prepareProcessor($daux, $input, $output, $width); + $this->prepareProcessor($daux, $width); // Generate the tree $daux->generateTree(); @@ -57,16 +79,4 @@ class Generate extends DauxCommand return 0; } - - protected function prepareProcessor(Daux $daux, InputInterface $input, OutputInterface $output, $width) - { - if ($input->getOption('processor')) { - $daux->getParams()['processor'] = $input->getOption('processor'); - } - - $class = $daux->getProcessorClass(); - if (!empty($class)) { - $daux->setProcessor(new $class($daux, $output, $width)); - } - } } diff --git a/libs/Console/Serve.php b/libs/Console/Serve.php index 8e1465e..cf8e738 100755 --- a/libs/Console/Serve.php +++ b/libs/Console/Serve.php @@ -6,6 +6,7 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Process\PhpExecutableFinder; use Symfony\Component\Process\ProcessUtils; +use Symfony\Component\Console\Terminal; use Todaymade\Daux\Daux; use Todaymade\Daux\Server\Server; @@ -19,8 +20,6 @@ class Serve extends DauxCommand ->setName('serve') ->setDescription('Serve documentation') - // Serve the current documentation - ->addOption('serve', null, InputOption::VALUE_NONE, 'Serve the current directory') ->addOption('host', null, InputOption::VALUE_REQUIRED, 'The host to serve on', 'localhost') ->addOption('port', null, InputOption::VALUE_REQUIRED, 'The port to serve on', 8085); } @@ -30,17 +29,27 @@ class Serve extends DauxCommand $host = $input->getOption('host'); $port = $input->getOption('port'); - $daux = $this->prepareDaux($input, $output); + $builder = $this->prepareConfig(Daux::LIVE_MODE, $input, $output); // Daux can only serve HTML - $daux->getParams()->setFormat('html'); + $builder->withFormat('html'); + + $daux = new Daux($builder->build(), $output); + + $width = (new Terminal)->getWidth(); + + // Instiantiate the processor if one is defined + $this->prepareProcessor($daux, $width); + + // Write the current configuration to a file to read it from the other serving side + $file = tmpfile(); + $path = stream_get_meta_data($file)['uri']; + fwrite($file, serialize($daux->getConfig())); chdir(__DIR__ . '/../../'); + putenv('DAUX_CONFIG='. $path); putenv('DAUX_VERBOSITY=' . $output->getVerbosity()); - putenv('DAUX_SOURCE=' . $daux->getParams()->getDocumentationDirectory()); - putenv('DAUX_THEME=' . $daux->getParams()->getThemesPath()); - putenv('DAUX_CONFIGURATION=' . $daux->getParams()->getConfigurationOverrideFile()); putenv('DAUX_EXTENSION=' . DAUX_EXTENSION); $base = escapeshellarg(__DIR__ . '/../../'); @@ -49,6 +58,7 @@ class Serve extends DauxCommand echo "Daux development server started on http://{$host}:{$port}/\n"; passthru("{$binary} -S {$host}:{$port} {$base}/index.php"); + fclose($file); return 0; } diff --git a/libs/ContentTypes/Markdown/CommonMarkConverter.php b/libs/ContentTypes/Markdown/CommonMarkConverter.php index d145c34..0a79e20 100644 --- a/libs/ContentTypes/Markdown/CommonMarkConverter.php +++ b/libs/ContentTypes/Markdown/CommonMarkConverter.php @@ -25,8 +25,8 @@ class CommonMarkConverter extends \League\CommonMark\CommonMarkConverter $this->extendEnvironment($environment, $config['daux']); - if (array_key_exists('processor_instance', $config['daux'])) { - $config['daux']['processor_instance']->extendCommonMarkEnvironment($environment); + if ($config['daux']->hasProcessorInstance()) { + $config['daux']->getProcessorInstance()->extendCommonMarkEnvironment($environment); } parent::__construct($config, $environment); diff --git a/libs/ContentTypes/Markdown/ContentType.php b/libs/ContentTypes/Markdown/ContentType.php index 2687684..c1fb2db 100644 --- a/libs/ContentTypes/Markdown/ContentType.php +++ b/libs/ContentTypes/Markdown/ContentType.php @@ -49,20 +49,23 @@ class ContentType implements \Todaymade\Daux\ContentTypes\ContentType { $this->config->setCurrentPage($node); - if (!$this->config->canCache()) { - return $this->doConversion($raw); - } + $can_cache = $this->config->canCache(); // TODO :: add daux version to cache key $cacheKey = $this->config->getCacheKey() . sha1($raw); $payload = Cache::get($cacheKey); - if ($payload) { + if ($can_cache && $payload) { Daux::writeln("Using cached version", OutputInterface::VERBOSITY_VERBOSE); - } else { - Daux::writeln("Not found in the cache, generating...", OutputInterface::VERBOSITY_VERBOSE); + } + + if (!$can_cache || !$payload) { + Daux::writeln($can_cache ? "Not found in the cache, generating..." : "Cache disabled, generating...", OutputInterface::VERBOSITY_VERBOSE); $payload = $this->doConversion($raw); + } + + if ($can_cache) { Cache::put($cacheKey, $payload); } diff --git a/libs/Daux.php b/libs/Daux.php index 0f99e63..eb66fe5 100644 --- a/libs/Daux.php +++ b/libs/Daux.php @@ -15,18 +15,13 @@ class Daux public static $output; - /** @var string */ - public $local_base; - /** @var \Todaymade\Daux\Format\Base\Generator */ protected $generator; /** @var ContentTypeHandler */ protected $typeHandler; - /** - * @var string[] - */ + /** @var string[] */ protected $validExtensions; /** @var Processor */ @@ -36,155 +31,17 @@ class Daux public $tree; /** @var Config */ - public $options; - - /** @var string */ - private $mode; + public $config; /** @var bool */ private $merged_tree = false; - /** - * @param string $mode - */ - public function __construct($mode, OutputInterface $output) + public function __construct(Config $config, OutputInterface $output) { Daux::$output = $output; - $this->mode = $mode; - $this->local_base = dirname(__DIR__); - - // global.json - $this->loadBaseConfiguration(); - } - - /** - * @param string $override_file - * @throws Exception - */ - public function initializeConfiguration($override_file = null) - { - $params = $this->getParams(); - - // Validate and set theme path - $params->setDocumentationDirectory( - $docs_path = $this->normalizeDocumentationPath($this->getParams()->getDocumentationDirectory()) - ); - - // Read documentation overrides - $this->loadConfiguration($docs_path . DIRECTORY_SEPARATOR . 'config.json'); - - // Read command line overrides - $override_file = $this->getConfigurationOverride($override_file); - if ($override_file !== null) { - $params->setConfigurationOverrideFile($override_file); - $this->loadConfiguration($override_file); - } - - // Validate and set theme path - $params->setThemesPath($this->normalizeThemePath($params->getThemesDirectory())); - - // Set a valid default timezone - if ($params->hasTimezone()) { - date_default_timezone_set($params->getTimezone()); - } elseif (!ini_get('date.timezone')) { - date_default_timezone_set('GMT'); - } - } - - /** - * Get the file requested for configuration overrides - * - * @param string|null $path - * @return string|null the path to a file to load for configuration overrides - * @throws Exception - */ - public function getConfigurationOverride($path) - { - $validPath = DauxHelper::findLocation($path, $this->local_base, 'DAUX_CONFIGURATION', 'file'); - - if ($validPath === null) { - return null; - } - - if (!$validPath) { - throw new Exception('The configuration override file does not exist. Check the path again : ' . $path); - } - - return $validPath; - } - - public function normalizeThemePath($path) - { - $validPath = DauxHelper::findLocation($path, $this->local_base, 'DAUX_THEME', 'dir'); - - if (!$validPath) { - throw new Exception('The Themes directory does not exist. Check the path again : ' . $path); - } - - return $validPath; - - } - - public function normalizeDocumentationPath($path) - { - $validPath = DauxHelper::findLocation($path, $this->local_base, 'DAUX_SOURCE', 'dir'); - - if (!$validPath) { - throw new Exception('The Docs directory does not exist. Check the path again : ' . $path); - } - - return $validPath; - } - - /** - * Load and validate the global configuration - * - * @throws Exception - */ - protected function loadBaseConfiguration() - { - $this->options = new Config(); - - // Set the default configuration - $this->options->merge([ - 'docs_directory' => 'docs', - 'valid_content_extensions' => ['md', 'markdown'], - - //Paths and tree - 'mode' => $this->mode, - 'local_base' => $this->local_base, - 'templates' => 'templates', - - 'index_key' => 'index.html', - 'base_page' => '', - 'base_url' => '', - ]); - - // Load the global configuration - $this->loadConfiguration($this->local_base . DIRECTORY_SEPARATOR . 'global.json', false); - } - - /** - * @param string $config_file - * @param bool $optional - * @throws Exception - */ - protected function loadConfiguration($config_file, $optional = true) - { - if (!file_exists($config_file)) { - if ($optional) { - return; - } - - throw new Exception('The configuration file is missing. Check path : ' . $config_file); - } - - $config = json_decode(file_get_contents($config_file), true); - if (!isset($config)) { - throw new Exception('The configuration file "' . $config_file . '" is corrupt. Is your JSON well-formed ?'); - } - $this->options->merge($config); + + $this->config = $config; } /** @@ -192,14 +49,14 @@ class Daux */ public function generateTree() { - $this->options['valid_content_extensions'] = $this->getContentExtensions(); + $this->config->setValidContentExtensions($this->getContentExtensions()); - $this->tree = new Root($this->getParams()); - Builder::build($this->tree, $this->options['ignore']); + $this->tree = new Root($this->getConfig()); + Builder::build($this->tree, $this->config->getIgnore()); // Apply the language name as Section title - if ($this->options->isMultilanguage()) { - foreach ($this->options['languages'] as $key => $node) { + if ($this->config->isMultilanguage()) { + foreach ($this->config->getLanguages() as $key => $node) { $this->tree->getEntries()[$key]->setTitle($node); } } @@ -216,22 +73,34 @@ class Daux /** * @return Config */ - public function getParams() + public function getConfig() { if ($this->tree && !$this->merged_tree) { - $this->options['tree'] = $this->tree; - $this->options['index'] = $this->tree->getIndexPage() ?: $this->tree->getFirstPage(); - if ($this->options->isMultilanguage()) { - foreach ($this->options['languages'] as $key => $name) { - $this->options['entry_page'][$key] = $this->tree->getEntries()[$key]->getFirstPage(); + $this->config->setTree($this->tree); + $this->config->setIndex($this->tree->getIndexPage() ?: $this->tree->getFirstPage()); + $entry_page = null; + if ($this->config->isMultilanguage()) { + $entry_page = []; + foreach ($this->config->getLanguages() as $key => $name) { + $entry_page[$key] = $this->tree->getEntries()[$key]->getFirstPage(); } } else { - $this->options['entry_page'] = $this->tree->getFirstPage(); + $entry_page= $this->tree->getFirstPage(); } + $this->config->setEntryPage($entry_page); $this->merged_tree = true; } - return $this->options; + return $this->config; + } + + /** + * @return Config + * @deprecated Use getConfig instead + */ + public function getParams() + { + return $this->getConfig(); } /** @@ -254,9 +123,9 @@ class Daux $this->processor = $processor; // This is not the cleanest but it's - // the best i've found to use the + // the best I've found to use the // processor in very remote places - $this->options['processor_instance'] = $processor; + $this->config->setProcessorInstance($processor); } public function getGenerators() @@ -272,10 +141,9 @@ class Daux return array_replace($default, $extended); } - public function getProcessorClass() { - $processor = $this->getParams()['processor']; + $processor = $this->getConfig()->getProcessor(); if (empty($processor)) { return null; @@ -318,7 +186,7 @@ class Daux $generators = $this->getGenerators(); - $format = $this->getParams()->getFormat(); + $format = $this->getConfig()->getFormat(); if (!array_key_exists($format, $generators)) { $message = "The format '$format' doesn't exist, did you forget to set your processor ?"; diff --git a/libs/DauxHelper.php b/libs/DauxHelper.php index 0b54fea..c902a33 100644 --- a/libs/DauxHelper.php +++ b/libs/DauxHelper.php @@ -16,52 +16,27 @@ class DauxHelper public static function rebaseConfiguration(Config $config, $base_url) { // Avoid changing the url if it is already correct - if ($config['base_url'] == $base_url && !empty($config['theme'])) { + if ($config->getBaseUrl() == $base_url && !empty($config->getTheme())) { return; } // Change base url for all links on the pages - $config['base_url'] = $config['base_page'] = $base_url; + $config['base_url'] = $base_url; $config['theme'] = static::getTheme($config, $base_url); - $config['image'] = str_replace('', $base_url, $config['image']); - } - - protected static function resolveVariant(Config $params) - { - if (array_key_exists('theme-variant', $params['html'])) { - return; - } - - if (is_dir(realpath(($params->getThemesPath() . DIRECTORY_SEPARATOR . $params['html']['theme'])))) { - return; - } - - $theme = explode('-', $params['html']['theme']); - - // do we have a variant or only a theme ? - if (isset($theme[1])) { - $params['html']['theme-variant'] = array_pop($theme); - $params['html']['theme'] = implode('-', $theme); - } else { - $params['html']['theme'] = array_pop($theme); - } - - if (!is_dir(realpath($params->getThemesPath() . DIRECTORY_SEPARATOR . $params['html']['theme']))) { - throw new \RuntimeException("Theme '{$params['html']['theme']}' not found"); - } + $config['image'] = str_replace('', $base_url, $config->getImage()); } /** - * @param Config $params + * @param Config $config * @param string $current_url * @return array */ - protected static function getTheme(Config $params, $current_url) + protected static function getTheme(Config $config, $current_url) { - self::resolveVariant($params); + $htmlTheme = $config->getHTML()->getTheme(); - $theme_folder = $params->getThemesPath() . DIRECTORY_SEPARATOR . $params['html']['theme']; - $theme_url = $params['base_url'] . 'themes/' . $params['html']['theme'] . '/'; + $theme_folder = $config->getThemesPath() . DIRECTORY_SEPARATOR . $htmlTheme; + $theme_url = $config->getBaseUrl() . 'themes/' . $htmlTheme . '/'; $theme = []; if (is_file($theme_folder . DIRECTORY_SEPARATOR . 'config.json')) { @@ -73,7 +48,7 @@ class DauxHelper //Default parameters for theme $theme += [ - 'name' => $params['html']['theme'], + 'name' => $htmlTheme, 'css' => [], 'js' => [], 'fonts' => [], @@ -82,8 +57,8 @@ class DauxHelper 'variants' => [], ]; - if (array_key_exists('theme-variant', $params['html'])) { - $variant = $params['html']['theme-variant']; + if ($config->getHTML()->hasThemeVariant()) { + $variant = $config->getHTML()->getThemeVariant(); if (!array_key_exists($variant, $theme['variants'])) { throw new Exception("Variant '$variant' not found for theme '$theme[name]'"); } @@ -104,7 +79,7 @@ class DauxHelper } $substitutions = [ - '' => $params['local_base'], + '' => $config->getLocalBase(), '' => $current_url, '' => $theme_url, ]; @@ -156,7 +131,7 @@ class DauxHelper */ public static function getFilenames(Config $config, $part) { - $extensions = implode('|', array_map('preg_quote', $config['valid_content_extensions'])) . '|html'; + $extensions = implode('|', array_map('preg_quote', $config->getValidContentExtensions())) . '|html'; $raw = preg_replace('/(.*)?\\.(' . $extensions . ')$/', '$1', $part); $raw = Builder::removeSortingInformations($raw); @@ -487,44 +462,6 @@ class DauxHelper return getcwd() . '/' . $path; } - /** - * @param string|null $path - * @param string $basedir - * @param string $var The constant name to check - * @param "dir"|"file" $type - * @return false|null|string - */ - public static function findLocation($path, $basedir, $var, $type) { - // VFS, used only in tests - if (substr($path, 0, 6) == "vfs://") { - return $path; - } - - // When running through `daux --serve` we set an environment variable to know where we started from - $env = getenv($var); - if ($env && DauxHelper::is($env, $type)) { - return $env; - } - - // If Path is explicitly null, it's useless to go further - if ($path == null) { - return null; - } - - // Check if it's relative to the current directory or an absolute path - if (DauxHelper::is($path, $type)) { - return DauxHelper::getAbsolutePath($path); - } - - // Check if it exists relative to Daux's root - $newPath = $basedir . DIRECTORY_SEPARATOR . $path; - if (DauxHelper::is($newPath, $type)) { - return $newPath; - } - - return false; - } - public static function is($path, $type) { return ($type == 'dir') ? is_dir($path) : file_exists($path); } @@ -545,7 +482,7 @@ class DauxHelper if ($url[0] == '!' || $url[0] == '/') { $url = ltrim($url, '!/'); - if ($file = DauxHelper::getFile($config['tree'], $url)) { + if ($file = DauxHelper::getFile($config->getTree(), $url)) { return $file; } @@ -560,7 +497,7 @@ class DauxHelper // If we didn't already try it, we'll // do a pass starting at the root - if (!$triedAbsolute && $file = DauxHelper::getFile($config['tree'], $url)) { + if (!$triedAbsolute && $file = DauxHelper::getFile($config->getTree(), $url)) { return $file; } diff --git a/libs/Format/Base/ContentPage.php b/libs/Format/Base/ContentPage.php index 7641085..4af078e 100644 --- a/libs/Format/Base/ContentPage.php +++ b/libs/Format/Base/ContentPage.php @@ -14,7 +14,7 @@ abstract class ContentPage extends SimplePage /** * @var Config */ - protected $params; + protected $config; /** * @var ContentType @@ -38,9 +38,17 @@ abstract class ContentPage extends SimplePage return $this->file; } - public function setParams(Config $params) + public function setConfig(Config $config) { - $this->params = $params; + $this->config = $config; + } + + /** + * @deprecated use setConfig instead + */ + public function setParams(Config $config) + { + $this->setConfig($config); } /** @@ -65,11 +73,11 @@ abstract class ContentPage extends SimplePage return $this->getPureContent(); } - public static function fromFile(Content $file, $params, ContentType $contentType) + public static function fromFile(Content $file, $config, ContentType $contentType) { $page = new static($file->getTitle(), $file->getContent()); $page->setFile($file); - $page->setParams($params); + $page->setConfig($config); $page->setContentType($contentType); return $page; diff --git a/libs/Format/Base/LiveGenerator.php b/libs/Format/Base/LiveGenerator.php index 97e14c6..0230719 100644 --- a/libs/Format/Base/LiveGenerator.php +++ b/libs/Format/Base/LiveGenerator.php @@ -7,8 +7,8 @@ interface LiveGenerator extends Generator { /** * @param Entry $node - * @param Config $params + * @param Config $config * @return \Todaymade\Daux\Format\Base\Page */ - public function generateOne(Entry $node, Config $params); + public function generateOne(Entry $node, Config $config); } diff --git a/libs/Format/Confluence/Config.php b/libs/Format/Confluence/Config.php new file mode 100644 index 0000000..8311a68 --- /dev/null +++ b/libs/Format/Confluence/Config.php @@ -0,0 +1,66 @@ +params['tree'])) + $content = (new EmbedImages($this->config->getTree())) ->embed( $content, $this->file, @@ -36,10 +36,9 @@ class ContentPage extends \Todaymade\Daux\Format\Base\ContentPage } ); - $intro = ''; - if (array_key_exists('confluence', $this->params) && array_key_exists('header', $this->params['confluence']) && !empty($this->params['confluence']['header'])) { - $intro = '' . $this->params['confluence']['header'] . ''; + if ($this->config->getConfluenceConfiguration()->hasHeader()) { + $intro = '' . $this->config->getConfluenceConfiguration()->getHeader() . ''; } return $intro . $content; diff --git a/libs/Format/Confluence/ContentTypes/Markdown/FencedCodeRenderer.php b/libs/Format/Confluence/ContentTypes/Markdown/FencedCodeRenderer.php index b39d5aa..f53ed67 100644 --- a/libs/Format/Confluence/ContentTypes/Markdown/FencedCodeRenderer.php +++ b/libs/Format/Confluence/ContentTypes/Markdown/FencedCodeRenderer.php @@ -48,12 +48,12 @@ class FencedCodeRenderer extends CodeRenderer throw new \InvalidArgumentException('Incompatible block type: ' . get_class($block)); } - $language = $this->getLanguage($block->getInfoWords(), $htmlRenderer); + $language = $this->getLanguage($block->getInfoWords()); return $this->getHTMLElement($block->getStringContent(), $language); } - public function getLanguage($infoWords, ElementRendererInterface $htmlRenderer) + public function getLanguage($infoWords) { if (count($infoWords) === 0 || strlen($infoWords[0]) === 0) { return false; diff --git a/libs/Format/Confluence/Generator.php b/libs/Format/Confluence/Generator.php index 0c70c23..a452651 100644 --- a/libs/Format/Confluence/Generator.php +++ b/libs/Format/Confluence/Generator.php @@ -30,7 +30,7 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator public function checkConfiguration() { - $config = $this->daux->getParams(); + $config = $this->daux->getConfig(); $confluence = $config->getConfluenceConfiguration(); if ($confluence == null) { @@ -60,7 +60,7 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator public function getContentTypes() { return [ - new ContentTypes\Markdown\ContentType($this->daux->getParams()), + new ContentTypes\Markdown\ContentType($this->daux->getConfig()), ]; } @@ -69,10 +69,10 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator */ public function generateAll(InputInterface $input, OutputInterface $output, $width) { - $params = $this->daux->getParams(); + $config = $this->daux->getConfig(); - $confluence = $params['confluence']; - $this->prefix = trim($confluence['prefix']) . ' '; + $confluence = $config->getConfluenceConfiguration(); + $this->prefix = trim($confluence->getPrefix()) . ' '; if ($this->prefix == ' ') { $this->prefix = ''; } @@ -80,9 +80,9 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator $tree = $this->runAction( 'Generating Tree ...', $width, - function() use ($params) { - $tree = $this->generateRecursive($this->daux->tree, $params); - $tree['title'] = $this->prefix . $params['title']; + function() use ($config) { + $tree = $this->generateRecursive($this->daux->tree, $config); + $tree['title'] = $this->prefix . $config->getTitle(); return $tree; } @@ -96,31 +96,31 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator $publisher->publish($tree); } - private function generateRecursive(Directory $tree, Config $params, $base_url = '') + private function generateRecursive(Directory $tree, Config $config, $base_url = '') { $final = ['title' => $this->prefix . $tree->getTitle()]; - $params['base_url'] = $params['base_page'] = $base_url; + $config['base_url'] = $base_url; - $params['image'] = str_replace('', $base_url, $params['image']); + $config->setImage(str_replace('', $base_url, $config->getImage())); if ($base_url !== '') { - $params['entry_page'] = $tree->getFirstPage(); + $config->setEntryPage($tree->getFirstPage()); } foreach ($tree->getEntries() as $key => $node) { if ($node instanceof Directory) { $final['children'][$this->prefix . $node->getTitle()] = $this->generateRecursive( $node, - $params, + $config, '../' . $base_url ); } elseif ($node instanceof Content) { - $params['request'] = $node->getUrl(); + $config->setRequest($node->getUrl()); $contentType = $this->daux->getContentTypeHandler()->getType($node); $data = [ 'title' => $this->prefix . $node->getTitle(), 'file' => $node, - 'page' => ContentPage::fromFile($node, $params, $contentType), + 'page' => ContentPage::fromFile($node, $config, $contentType), ]; if ($key == 'index.html') { diff --git a/libs/Format/Confluence/Publisher.php b/libs/Format/Confluence/Publisher.php index ec13a4e..f5abe20 100644 --- a/libs/Format/Confluence/Publisher.php +++ b/libs/Format/Confluence/Publisher.php @@ -13,7 +13,7 @@ class Publisher protected $client; /** - * @var array + * @var Config */ protected $confluence; @@ -30,12 +30,12 @@ class Publisher /** * @param $confluence */ - public function __construct($confluence) + public function __construct(Config $confluence) { $this->confluence = $confluence; - $this->client = new Api($confluence['base_url'], $confluence['user'], $confluence['pass']); - $this->client->setSpace($confluence['space_id']); + $this->client = new Api($confluence->getBaseUrl(), $confluence->getUser(), $confluence->getPassword()); + $this->client->setSpace($confluence->getSpaceId()); } public function run($title, $closure) @@ -64,22 +64,21 @@ class Publisher $published = $this->run( "Create placeholder pages...", function() use ($tree, $published) { - return $this->createRecursive($this->confluence['ancestor_id'], $tree, $published); + return $this->createRecursive($this->confluence->getAncestorId(), $tree, $published); } ); $this->output->writeLn('Publishing updates...'); - $published = $this->updateRecursive($this->confluence['ancestor_id'], $tree, $published); + $published = $this->updateRecursive($this->confluence->getAncestorId(), $tree, $published); - $shouldDelete = array_key_exists('delete', $this->confluence) && $this->confluence['delete']; - $delete = new PublisherDelete($this->output, $shouldDelete, $this->client); + $delete = new PublisherDelete($this->output, $this->confluence->shouldAutoDeleteOrphanedPages(), $this->client); $delete->handle($published); } protected function getRootPage($tree) { - if (array_key_exists('ancestor_id', $this->confluence)) { - $pages = $this->client->getList($this->confluence['ancestor_id']); + if ($this->confluence->hasAncestorId()) { + $pages = $this->client->getList($this->confluence->getAncestorId()); foreach ($pages as $page) { if ($page['title'] == $tree['title']) { return $page; @@ -87,9 +86,9 @@ class Publisher } } - if (array_key_exists('root_id', $this->confluence)) { - $published = $this->client->getPage($this->confluence['root_id']); - $this->confluence['ancestor_id'] = $published['ancestor_id']; + if ($this->confluence->hasRootId()) { + $published = $this->client->getPage($this->confluence->getRootId()); + $this->confluence->setAncestorId($published['ancestor_id']); return $published; } @@ -178,7 +177,7 @@ class Publisher protected function updatePage($parent_id, $entry, $published) { - $updateThreshold = array_key_exists('update_threshold', $this->confluence) ? $this->confluence['update_threshold'] : 2; + $updateThreshold = $this->confluence->getUpdateThreshold(); $this->run( '- ' . PublisherUtilities::niceTitle($entry['file']->getUrl()), diff --git a/libs/Format/Confluence/PublisherDelete.php b/libs/Format/Confluence/PublisherDelete.php index b3a94a6..6c5a0b5 100644 --- a/libs/Format/Confluence/PublisherDelete.php +++ b/libs/Format/Confluence/PublisherDelete.php @@ -22,7 +22,7 @@ class PublisherDelete */ protected $client; - public function __construct($output, $delete, $client) + public function __construct($output, bool $delete, $client) { $this->output = $output; $this->delete = $delete; @@ -55,7 +55,6 @@ class PublisherDelete if ($this->delete) { $this->doDelete(); - } else { $this->displayDeletable(); } diff --git a/libs/Format/HTML/Config.php b/libs/Format/HTML/Config.php index affd476..4ea352a 100644 --- a/libs/Format/HTML/Config.php +++ b/libs/Format/HTML/Config.php @@ -20,7 +20,6 @@ class Config extends BaseConfig if (is_string($this['edit_on'])) { return $this->prepareGithubUrl($this['edit_on']); } else { - $this['edit_on']['basepath'] = rtrim($this['edit_on']['basepath'], '/'); return $this['edit_on']; @@ -28,9 +27,154 @@ class Config extends BaseConfig } if (array_key_exists('edit_on_github', $this)) { - return $this->prepareGithubUrl($this['edit_on_github']); + return $this->prepareGithubUrl($this->getValue('edit_on_github')); } return null; } + + public function hasSearch() { + return $this->hasValue('search') && $this->getValue('search'); + } + + public function showDateModified() + { + return $this->hasValue('date_modified') && $this->getValue('date_modified'); + } + + public function showPreviousNextLinks() + { + if ($this->hasValue('jump_buttons')) { + return $this->getValue('jump_buttons'); + } + + return true; + } + + public function showCodeToggle() + { + if ($this->hasValue('toggle_code')) { + return $this->getValue('toggle_code'); + } + + return true; + } + + public function hasAutomaticTableOfContents(): bool + { + return $this->hasValue('auto_toc') && $this->getValue('auto_toc'); + } + + public function hasGoogleAnalytics() + { + return $this->hasValue('google_analytics'); + } + + public function getGoogleAnalyticsId() + { + return $this->getValue('google_analytics'); + } + + public function hasPiwikAnalytics() + { + return $this->hasValue('piwik_analytics') && $this->hasValue('piwik_analytics_id'); + } + + public function getPiwikAnalyticsId() + { + return $this->getValue('piwik_analytics_id'); + } + + public function getPiwikAnalyticsUrl() + { + return $this->getValue('piwik_analytics'); + } + + public function hasPoweredBy() + { + return $this->hasValue('powered_by') && !empty($this->getValue('powered_by')); + } + + public function getPoweredBy() + { + return $this->getValue('powered_by'); + } + + public function hasTwitterHandles() + { + return $this->hasValue('twitter') && !empty($this->getValue('twitter')); + } + + public function getTwitterHandles() + { + return $this->getValue('twitter'); + } + + public function hasLinks() + { + return $this->hasValue('links') && !empty($this->getValue('links')); + } + + public function getLinks() + { + return $this->getValue('links'); + } + + public function hasRepository() + { + return $this->hasValue('repo') && !empty($this->getValue('repo')); + } + + public function getRepository() + { + return $this->getValue('repo'); + } + + public function hasButtons() + { + return $this->hasValue('buttons') && !empty($this->getValue('buttons')); + } + + public function getButtons() + { + return $this->getValue('buttons'); + } + + public function hasLandingPage() + { + if ($this->hasValue('auto_landing')) { + return $this->getValue('auto_landing'); + } + + return true; + } + + public function hasBreadcrumbs() + { + if ($this->hasValue('breadcrumbs')) { + return $this->getValue('breadcrumbs'); + } + + return true; + } + + public function getBreadcrumbsSeparator() + { + return $this->getValue('breadcrumb_separator'); + } + + public function getTheme() + { + return $this->getValue('theme'); + } + + public function hasThemeVariant() + { + return $this->hasValue('theme-variant') && !empty($this->getValue('theme-variant')); + } + + public function getThemeVariant() + { + return $this->getValue('theme-variant'); + } } diff --git a/libs/Format/HTML/ContentPage.php b/libs/Format/HTML/ContentPage.php index 79e9da1..72d8a11 100644 --- a/libs/Format/HTML/ContentPage.php +++ b/libs/Format/HTML/ContentPage.php @@ -4,7 +4,14 @@ use Todaymade\Daux\Tree\Root; class ContentPage extends \Todaymade\Daux\Format\Base\ContentPage { + /** + * @var string + */ private $language; + + /** + * @var bool + */ private $homepage; /** @@ -12,24 +19,19 @@ class ContentPage extends \Todaymade\Daux\Format\Base\ContentPage */ public $templateRenderer; - private function isHomepage() + private function isHomepage(): bool { // If the current page isn't the index, no chance it is the landing page if ($this->file->getParent()->getIndexPage() != $this->file) { return false; } - // If the direct parent is root, this is the homage + // If the direct parent is root, this is the homepage return $this->file->getParent() instanceof Root; } - private function isLanding() { - // If we don't have the auto_landing parameter, we don't want any homepage - if (array_key_exists('auto_landing', $this->params['html']) && !$this->params['html']['auto_landing']) { - return false; - } - - return $this->homepage; + private function isLanding(): bool { + return $this->config->getHTML()->hasLandingPage() && $this->homepage; } private function initialize() @@ -37,7 +39,7 @@ class ContentPage extends \Todaymade\Daux\Format\Base\ContentPage $this->homepage = $this->isHomepage(); $this->language = ''; - if ($this->params->isMultilanguage() && count($this->file->getParents())) { + if ($this->config->isMultilanguage() && count($this->file->getParents())) { $language_dir = $this->file->getParents()[0]; $this->language = $language_dir->getName(); } @@ -67,16 +69,16 @@ class ContentPage extends \Todaymade\Daux\Format\Base\ContentPage protected function generatePage() { $this->initialize(); - $params = $this->params; + $config = $this->config; $entry_page = []; if ($this->homepage) { - if ($params->isMultilanguage()) { - foreach ($params['languages'] as $key => $name) { - $entry_page[$name] = $params['base_page'] . $params['entry_page'][$key]->getUrl(); + if ($config->isMultilanguage()) { + foreach ($config->getLanguages() as $key => $name) { + $entry_page[$name] = $config->getBasePage() . $config->getEntryPage()[$key]->getUrl(); } } else { - $entry_page['__VIEW_DOCUMENTATION__'] = $params['base_page'] . $params['entry_page']->getUrl(); + $entry_page['__VIEW_DOCUMENTATION__'] = $config->getBasePage() . $config->getEntryPage()->getUrl(); } } @@ -90,24 +92,24 @@ class ContentPage extends \Todaymade\Daux\Format\Base\ContentPage 'relative_path' => $this->file->getRelativePath(), 'modified_time' => filemtime($this->file->getPath()), 'markdown' => $this->content, - 'request' => $params['request'], + 'request' => $config->getRequest(), 'content' => $this->getPureContent(), - 'breadcrumbs' => $params['html']['breadcrumbs'], + 'breadcrumbs' => $config->getHTML()->hasBreadcrumbs(), 'prev' => $this->file->getPrevious(), 'next' => $this->file->getNext(), 'attributes' => $this->file->getAttribute() ]; if ($page['breadcrumbs']) { - $page['breadcrumb_trail'] = $this->getBreadcrumbTrail($this->file->getParents(), $params->isMultilanguage()); - $page['breadcrumb_separator'] = $params['html']['breadcrumb_separator']; + $page['breadcrumb_trail'] = $this->getBreadcrumbTrail($this->file->getParents(), $config->isMultilanguage()); + $page['breadcrumb_separator'] = $this->config->getHTML()->getBreadcrumbsSeparator(); if ($this->homepage) { $page['breadcrumb_trail'] = [['title' => $this->file->getTitle(), 'url' => '']]; } } - $context = ['page' => $page, 'params' => $params]; + $context = ['page' => $page, 'config' => $config]; $template = "theme::content"; if ($this->isLanding()) { diff --git a/libs/Format/HTML/ContentTypes/Markdown/TOC/Processor.php b/libs/Format/HTML/ContentTypes/Markdown/TOC/Processor.php index 995ad56..07fe77e 100644 --- a/libs/Format/HTML/ContentTypes/Markdown/TOC/Processor.php +++ b/libs/Format/HTML/ContentTypes/Markdown/TOC/Processor.php @@ -17,6 +17,9 @@ use Todaymade\Daux\ContentTypes\Markdown\TableOfContents; class Processor { + /** + * @var Config + */ protected $config; public function __construct(Config $config) @@ -24,11 +27,6 @@ class Processor $this->config = $config; } - public function hasAutoTOC() - { - return array_key_exists('html', $this->config) && array_key_exists('auto_toc', $this->config['html']) && $this->config['html']['auto_toc']; - } - /** * @param DocumentParsedEvent $event * @@ -60,7 +58,7 @@ class Processor $headings[] = new Entry($node); } - if (count($headings) && (count($tocs) || $this->hasAutoTOC())) { + if (count($headings) && (count($tocs) || $this->config->getHTML()->hasAutomaticTableOfContents())) { $generated = $this->generate($headings); if (count($tocs)) { diff --git a/libs/Format/HTML/Generator.php b/libs/Format/HTML/Generator.php index dbf46c0..3eb41ca 100755 --- a/libs/Format/HTML/Generator.php +++ b/libs/Format/HTML/Generator.php @@ -31,11 +31,11 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator */ public function __construct(Daux $daux) { - $params = $daux->getParams(); + $config = $daux->getConfig(); $this->daux = $daux; - $this->templateRenderer = new Template($params); - $params->templateRenderer = $this->templateRenderer; + $this->templateRenderer = new Template($config); + $config->templateRenderer = $this->templateRenderer; } /** @@ -44,7 +44,7 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator public function getContentTypes() { return [ - 'markdown' => new ContentType($this->daux->getParams()), + 'markdown' => new ContentType($this->daux->getConfig()), ]; } @@ -52,35 +52,31 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator { $destination = $input->getOption('destination'); - $params = $this->daux->getParams(); + $config = $this->daux->getConfig(); if (is_null($destination)) { - $destination = $this->daux->local_base . DIRECTORY_SEPARATOR . 'static'; + $destination = $config->getLocalBase() . DIRECTORY_SEPARATOR . 'static'; } $this->runAction( 'Copying Static assets ...', $width, - function() use ($destination, $params) { + function() use ($destination, $config) { $this->ensureEmptyDestination($destination); - $this->copyThemes($destination, $params->getThemesPath()); + $this->copyThemes($destination, $config->getThemesPath()); } ); $output->writeLn('Generating ...'); - if (!array_key_exists('search', $params['html']) || !$params['html']['search']) { - $params['html']['search'] = $input->getOption('search'); - } - - $this->generateRecursive($this->daux->tree, $destination, $params, $output, $width, $params['html']['search']); + $this->generateRecursive($this->daux->tree, $destination, $config, $output, $width, $config->getHTML()->hasSearch()); GeneratorHelper::copyRecursive( - $this->daux->local_base . DIRECTORY_SEPARATOR . 'daux_libraries' . DIRECTORY_SEPARATOR, + $config->getLocalBase() . DIRECTORY_SEPARATOR . 'daux_libraries' . DIRECTORY_SEPARATOR, $destination . DIRECTORY_SEPARATOR . 'daux_libraries' ); - if ($params['html']['search']) { + if ($config->getHTML()->hasSearch()) { file_put_contents( $destination . DIRECTORY_SEPARATOR . 'daux_search_index.json', json_encode(['pages' => $this->indexed_pages]) @@ -147,34 +143,34 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator * * @param Directory $tree * @param string $output_dir - * @param \Todaymade\Daux\Config $params + * @param \Todaymade\Daux\Config $config * @param OutputInterface $output * @param int $width * @param bool $index_pages * @param string $base_url * @throws \Exception */ - private function generateRecursive(Directory $tree, $output_dir, $params, $output, $width, $index_pages, $base_url = '') + private function generateRecursive(Directory $tree, $output_dir, $config, $output, $width, $index_pages, $base_url = '') { - DauxHelper::rebaseConfiguration($params, $base_url); + DauxHelper::rebaseConfiguration($config, $base_url); - if ($base_url !== '' && empty($params['entry_page'])) { - $params['entry_page'] = $tree->getFirstPage(); + if ($base_url !== '' && !$config->hasEntryPage()) { + $config->setEntryPage($tree->getFirstPage()); } foreach ($tree->getEntries() as $key => $node) { if ($node instanceof Directory) { $new_output_dir = $output_dir . DIRECTORY_SEPARATOR . $key; mkdir($new_output_dir); - $this->generateRecursive($node, $new_output_dir, $params, $output, $width, $index_pages, '../' . $base_url); + $this->generateRecursive($node, $new_output_dir, $config, $output, $width, $index_pages, '../' . $base_url); - // Rebase configuration again as $params is a shared object - DauxHelper::rebaseConfiguration($params, $base_url); + // Rebase configuration again as $config is a shared object + DauxHelper::rebaseConfiguration($config, $base_url); } else { $this->runAction( '- ' . $node->getUrl(), $width, - function() use ($node, $output_dir, $key, $params, $index_pages) { + function() use ($node, $output_dir, $key, $config, $index_pages) { if ($node instanceof Raw) { copy($node->getPath(), $output_dir . DIRECTORY_SEPARATOR . $key); @@ -183,7 +179,7 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator $this->daux->tree->setActiveNode($node); - $generated = $this->generateOne($node, $params); + $generated = $this->generateOne($node, $config); file_put_contents($output_dir . DIRECTORY_SEPARATOR . $key, $generated->getContent()); if ($index_pages) { $this->indexed_pages[] = [ @@ -201,10 +197,10 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator /** * @param Entry $node - * @param Config $params + * @param Config $config * @return \Todaymade\Daux\Format\Base\Page */ - public function generateOne(Entry $node, Config $params) + public function generateOne(Entry $node, Config $config) { if ($node instanceof Raw) { return new RawPage($node->getPath()); @@ -214,9 +210,9 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator return new ComputedRawPage($node); } - $params['request'] = $node->getUrl(); + $config->setRequest($node->getUrl()); - $contentPage = ContentPage::fromFile($node, $params, $this->daux->getContentTypeHandler()->getType($node)); + $contentPage = ContentPage::fromFile($node, $config, $this->daux->getContentTypeHandler()->getType($node)); $contentPage->templateRenderer = $this->templateRenderer; return $contentPage; diff --git a/libs/Format/HTML/Template.php b/libs/Format/HTML/Template.php index 1ab8ce9..28fc6ae 100644 --- a/libs/Format/HTML/Template.php +++ b/libs/Format/HTML/Template.php @@ -13,25 +13,25 @@ class Template { protected $engine; - protected $params; + protected $config; /** * @param string $base * @param string $theme */ - public function __construct(Config $params) + public function __construct(Config $config) { - $this->params = $params; + $this->config = $config; } - public function getEngine(Config $params) + public function getEngine(Config $config) { if ($this->engine) { return $this->engine; } - $base = $params['templates']; - $theme = $params['theme']['templates']; + $base = $config->getTemplates(); + $theme = $config->getTheme()->getTemplates(); // Use internal templates if no templates // dir exists in the working directory @@ -60,14 +60,15 @@ class Template */ public function render($name, array $data = []) { - $engine = $this->getEngine($data['params']); + $engine = $this->getEngine($data['config']); $engine->addData([ - 'base_url' => $data['params']['base_url'], - 'base_page' => $data['params']['base_page'], + 'base_url' => $data['config']->getBaseUrl(), + 'base_page' => $data['config']->getBasePage(), 'page' => $data['page'], - 'params' => $data['params'], - 'tree' => $data['params']['tree'], + 'params' => $data['config'], // legacy name for config + 'config' => $data['config'], + 'tree' => $data['config']['tree'], ]); Daux::writeln("Rendering template '$name'", OutputInterface::VERBOSITY_VERBOSE); @@ -84,7 +85,7 @@ class Template }); $engine->registerFunction('translate', function($key) { - $language = $this->params['language']; + $language = $this->config->getLanguage(); if (isset($this->engine->getData('page')['page'])) { $page = $this->engine->getData('page'); @@ -93,14 +94,12 @@ class Template } } - if (array_key_exists($language, $this->params['strings'])) { - if (array_key_exists($key, $this->params['strings'][$language])) { - return $this->params['strings'][$language][$key]; - } + if ($this->config->hasTranslationKey($language, $key)) { + return $this->config->getTranslationKey($language, $key); } - if (array_key_exists($key, $this->params['strings']['en'])) { - return $this->params['strings']['en'][$key]; + if ($this->config->hasTranslationKey('en', $key)) { + return $this->config->getTranslationKey('en', $key); } return "Unknown key $key"; diff --git a/libs/Format/HTML/Theme.php b/libs/Format/HTML/Theme.php new file mode 100644 index 0000000..f2a9e9e --- /dev/null +++ b/libs/Format/HTML/Theme.php @@ -0,0 +1,26 @@ +getValue('fonts'); + } + + public function getCSS() { + return $this->getValue('css'); + } + + public function getJS() { + return $this->getValue('js'); + } + + public function getFavicon() { + return $this->getValue('favicon'); + } + + public function getTemplates() { + return $this->getValue('templates'); + } +} diff --git a/libs/Format/HTMLFile/ContentPage.php b/libs/Format/HTMLFile/ContentPage.php index a672b6f..ceb1f12 100644 --- a/libs/Format/HTMLFile/ContentPage.php +++ b/libs/Format/HTMLFile/ContentPage.php @@ -13,7 +13,7 @@ class ContentPage extends \Todaymade\Daux\Format\Base\ContentPage // Embed images // We do it after generation so we can catch the images that were in html already - $content = (new EmbedImages($this->params['tree'])) + $content = (new EmbedImages($this->config->getTree())) ->embed( $content, $this->file, diff --git a/libs/Format/HTMLFile/Generator.php b/libs/Format/HTMLFile/Generator.php index 77d7110..6161491 100644 --- a/libs/Format/HTMLFile/Generator.php +++ b/libs/Format/HTMLFile/Generator.php @@ -23,11 +23,11 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator */ public function __construct(Daux $daux) { - $params = $daux->getParams(); + $config = $daux->getConfig(); $this->daux = $daux; - $this->templateRenderer = new Template($params); - $params->templateRenderer = $this->templateRenderer; + $this->templateRenderer = new Template($config); + $config->templateRenderer = $this->templateRenderer; } /** @@ -36,7 +36,7 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator public function getContentTypes() { return [ - 'markdown' => new ContentType($this->daux->getParams()), + 'markdown' => new ContentType($this->daux->getConfig()), ]; } @@ -47,9 +47,9 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator { $destination = $input->getOption('destination'); - $params = $this->daux->getParams(); + $config = $this->daux->getConfig(); if (is_null($destination)) { - $destination = $this->daux->local_base . DIRECTORY_SEPARATOR . 'static'; + $destination = $this->config->getLocalBase() . DIRECTORY_SEPARATOR . 'static'; } $this->runAction( @@ -61,9 +61,9 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator ); $data = [ - 'author' => $params['author'], - 'title' => $params['title'], - 'subject' => $params['tagline'] + 'author' => $config->getAuthor(), + 'title' => $config->getTitle(), + 'subject' => $config->getTagline() ]; $book = new Book($this->daux->tree, $data); @@ -73,9 +73,9 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator $this->runAction( 'Generating ' . $current->getTitle(), $width, - function () use ($book, $current, $params) { + function () use ($book, $current, $config) { $contentType = $this->daux->getContentTypeHandler()->getType($current); - $content = ContentPage::fromFile($current, $params, $contentType); + $content = ContentPage::fromFile($current, $config, $contentType); $content->templateRenderer = $this->templateRenderer; $content = $content->getContent(); $book->addPage($current, $content); diff --git a/libs/FormatDate.php b/libs/FormatDate.php index 464e812..3b09dd9 100644 --- a/libs/FormatDate.php +++ b/libs/FormatDate.php @@ -4,8 +4,8 @@ use IntlDateFormatter; class FormatDate { - public static function format($params, $date) { - $locale = $params['language']; + public static function format($config, $date) { + $locale = $config->getLanguage(); $datetype = IntlDateFormatter::LONG; $timetype = IntlDateFormatter::SHORT; $timezone = null; diff --git a/libs/Server/ErrorPage.php b/libs/Server/ErrorPage.php index f9084d3..c6c81dd 100644 --- a/libs/Server/ErrorPage.php +++ b/libs/Server/ErrorPage.php @@ -12,17 +12,17 @@ class ErrorPage extends SimplePage /** * @var \Todaymade\Daux\Config */ - private $params; + private $config; /** * @param string $title * @param string $content - * @param \Todaymade\Daux\Config $params + * @param \Todaymade\Daux\Config $config */ - public function __construct($title, $content, $params) + public function __construct($title, $content, $config) { parent::__construct($title, $content); - $this->params = $params; + $this->config = $config; } /** @@ -30,15 +30,15 @@ class ErrorPage extends SimplePage */ protected function generatePage() { - $params = $this->params; + $config = $this->config; $page = [ 'title' => $this->title, 'content' => $this->getPureContent(), 'language' => '', ]; - $template = new Template($params); + $template = new Template($config); - return $template->render('error', ['page' => $page, 'params' => $params]); + return $template->render('error', ['page' => $page, 'config' => $config]); } } diff --git a/libs/Server/Server.php b/libs/Server/Server.php index 3a34ea3..144edda 100755 --- a/libs/Server/Server.php +++ b/libs/Server/Server.php @@ -6,6 +6,7 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Mime\MimeTypes; use Todaymade\Daux\Daux; +use Todaymade\Daux\ConfigBuilder; use Todaymade\Daux\DauxHelper; use Todaymade\Daux\Exception; use Todaymade\Daux\Format\Base\ComputedRawPage; @@ -16,7 +17,7 @@ use Todaymade\Daux\Format\HTML\RawPage; class Server { private $daux; - private $params; + private $config; private $base_url; /** @@ -34,18 +35,20 @@ class Server $verbosity = getenv('DAUX_VERBOSITY'); $output = new ConsoleOutput($verbosity); - $daux = new Daux(Daux::LIVE_MODE, $output); - $daux->initializeConfiguration(); + $configFile = getenv('DAUX_CONFIG'); + if ($configFile) { + $config = ConfigBuilder::fromFile($configFile); + } else { + $config = ConfigBuilder::withMode(Daux::LIVE_MODE)->build(); + } + + $daux = new Daux($config, $output); $class = $daux->getProcessorClass(); if (!empty($class)) { $daux->setProcessor(new $class($daux, $output, 0)); } - // Set this critical configuration - // for the tree generation - $daux->getParams()['index_key'] = 'index'; - // Improve the tree with a processor $daux->generateTree(); @@ -54,7 +57,7 @@ class Server try { $page = $server->handle(); } catch (NotFoundException $e) { - $page = new ErrorPage('An error occured', $e->getMessage(), $daux->getParams()); + $page = new ErrorPage('An error occured', $e->getMessage(), $daux->getConfig()); } $server->createResponse($page)->prepare($server->request)->send(); @@ -118,20 +121,14 @@ class Server /** * @return \Todaymade\Daux\Config */ - public function getParams() + public function getConfig() { - $params = $this->daux->getParams(); + $config = $this->daux->getConfig(); - DauxHelper::rebaseConfiguration($params, '//' . $this->base_url); - $params['base_page'] = '//' . $this->base_url; - if (!$this->daux->options['live']['clean_urls']) { - $params['base_page'] .= 'index.php/'; - } + DauxHelper::rebaseConfiguration($config, '//' . $this->base_url); - // Text search would be too slow on live server - $params['html']['search'] = false; - return $params; + return $config; } /** @@ -143,7 +140,7 @@ class Server */ public function handle() { - $this->params = $this->getParams(); + $this->config = $this->getConfig(); $request = substr($this->request->getRequestUri(), strlen($this->request->getBaseUrl()) + 1); @@ -167,7 +164,7 @@ class Server */ public function serveTheme($request) { - $file = $this->getParams()->getThemesPath() . $request; + $file = $this->getConfig()->getThemesPath() . $request; if (file_exists($file)) { return new RawPage($file); @@ -199,6 +196,6 @@ class Server ); } - return $this->daux->getGenerator()->generateOne($file, $this->params); + return $this->daux->getGenerator()->generateOne($file, $this->config); } } diff --git a/libs/Tree/Builder.php b/libs/Tree/Builder.php index 82772fd..db76d09 100644 --- a/libs/Tree/Builder.php +++ b/libs/Tree/Builder.php @@ -104,7 +104,7 @@ class Builder $config = $parent->getConfig(); - if (!in_array($file->getExtension(), $config['valid_content_extensions'])) { + if (!in_array($file->getExtension(), $config->getValidContentExtensions())) { $uri = $file->getFilename(); $entry = new Raw($parent, $uri, $file); @@ -122,7 +122,7 @@ class Builder $entry = new Content($parent, $uri, $file); - if ($entry->getUri() == $config['index_key']) { + if ($entry->getUri() == $config->getIndexKey()) { if ($parent instanceof Root) { $entry->setTitle($config->getTitle()); } else { @@ -184,7 +184,7 @@ class Builder $path .= '.md'; } - $raw = !in_array($extension, $parent->getConfig()['valid_content_extensions']); + $raw = !in_array($extension, $parent->getConfig()->getValidContentExtensions()); $title = $uri = $path; if (!$raw) { diff --git a/libs/Tree/Directory.php b/libs/Tree/Directory.php index 86955d1..f3d6b7a 100644 --- a/libs/Tree/Directory.php +++ b/libs/Tree/Directory.php @@ -127,7 +127,7 @@ class Directory extends Entry implements \ArrayAccess, \IteratorAggregate } public function getLocalIndexPage() { - $index_key = $this->getConfig()['index_key']; + $index_key = $this->getConfig()->getIndexKey(); if (isset($this->children[$index_key])) { return $this->children[$index_key]; @@ -141,8 +141,6 @@ class Directory extends Entry implements \ArrayAccess, \IteratorAggregate */ public function getIndexPage(): ?Content { - $index_key = $this->getConfig()['index_key']; - if ($this->getLocalIndexPage()) { return $this->getLocalIndexPage(); } @@ -161,7 +159,7 @@ class Directory extends Entry implements \ArrayAccess, \IteratorAggregate public function seekFirstPage(): ?Content { if ($this instanceof self) { - $index_key = $this->getConfig()['index_key']; + $index_key = $this->getConfig()->getIndexKey(); if (isset($this->children[$index_key])) { return $this->children[$index_key]; } diff --git a/libs/bootstrap.php b/libs/bootstrap.php index 8e5b669..07734fe 100644 --- a/libs/bootstrap.php +++ b/libs/bootstrap.php @@ -16,6 +16,8 @@ function loadApp() { $loader = loadApp(); +// This will define the path at which to +// find the daux processor extensions if ($loader) { $ext = __DIR__ . '/../daux'; if (is_dir(getcwd() . "/daux")) { diff --git a/templates/content.php b/templates/content.php index c710bec..2949c47 100644 --- a/templates/content.php +++ b/templates/content.php @@ -3,13 +3,13 @@ getHTML()->showPreviousNextLinks()) { ?>