diff options
author | Nils Adermann <naderman@naderman.de> | 2011-08-30 01:32:11 -0400 |
---|---|---|
committer | Nils Adermann <naderman@naderman.de> | 2011-09-29 16:15:53 +0200 |
commit | ea46feb11542a9cf54ce083ee0ad03f4c5e02a1e (patch) | |
tree | 0990527e0c05bd9da495a063350ec199eb2ed227 /phpBB | |
parent | 6ea6d50ccb9607429486a01d3144c7d32322e1b5 (diff) | |
download | forums-ea46feb11542a9cf54ce083ee0ad03f4c5e02a1e.tar forums-ea46feb11542a9cf54ce083ee0ad03f4c5e02a1e.tar.gz forums-ea46feb11542a9cf54ce083ee0ad03f4c5e02a1e.tar.bz2 forums-ea46feb11542a9cf54ce083ee0ad03f4c5e02a1e.tar.xz forums-ea46feb11542a9cf54ce083ee0ad03f4c5e02a1e.zip |
[feature/extension-manager] Add support for templates in extensions.
This commit adds a template path provider to separate the process of locating
(cached) paths in extensions from the template engine. The locator is supplied
with a list of paths from the path provider.
Admin templates can now be created in ext/<ext>/adm/style/ and regular
templates go into ext/<ext>/styles/<style>/template/. Extension templates
override regular templates. So if an extension supplies a file with a name
used in phpBB, the extension's file will be used.
A side-effect of this commit: Locator and Provider are now able to deal with
arbitrary levels of template inheritance. So we can expose this through
phpbb_template if we choose to, and allow styles to inherit from inherited
styles.
PHPBB3-10323
Diffstat (limited to 'phpBB')
-rw-r--r-- | phpBB/adm/index.php | 1 | ||||
-rw-r--r-- | phpBB/common.php | 5 | ||||
-rw-r--r-- | phpBB/includes/bbcode.php | 5 | ||||
-rw-r--r-- | phpBB/includes/functions_messenger.php | 5 | ||||
-rw-r--r-- | phpBB/includes/template/locator.php | 97 | ||||
-rw-r--r-- | phpBB/includes/template/path_provider.php | 137 | ||||
-rw-r--r-- | phpBB/includes/template/template.php | 67 | ||||
-rw-r--r-- | phpBB/install/index.php | 6 |
8 files changed, 234 insertions, 89 deletions
diff --git a/phpBB/adm/index.php b/phpBB/adm/index.php index 4f4d9ccedd..cb9e07bd70 100644 --- a/phpBB/adm/index.php +++ b/phpBB/adm/index.php @@ -52,6 +52,7 @@ $module_id = request_var('i', ''); $mode = request_var('mode', ''); // Set custom template for admin area +$template->set_ext_dir_prefix('adm/'); $template->set_custom_template($phpbb_admin_path . 'style', 'admin'); $template->assign_var('T_ASSETS_PATH', $phpbb_root_path . 'assets'); $template->assign_var('T_TEMPLATE_PATH', $phpbb_admin_path . 'style'); diff --git a/phpBB/common.php b/phpBB/common.php index 3cc9e57e46..279d5c481d 100644 --- a/phpBB/common.php +++ b/phpBB/common.php @@ -130,8 +130,9 @@ set_config_count(null, null, null, $config); // load extensions $phpbb_extension_manager = new phpbb_extension_manager($db, EXT_TABLE, $phpbb_root_path, ".$phpEx", $cache->get_driver()); -$template_locator = new phpbb_template_locator(); -$template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $template_locator); +$phpbb_template_locator = new phpbb_template_locator(); +$phpbb_template_path_provider = new phpbb_template_path_provider($phpbb_extension_manager); +$template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $phpbb_template_locator, $phpbb_template_path_provider); // Add own hook handler require($phpbb_root_path . 'includes/hooks/index.' . $phpEx); diff --git a/phpBB/includes/bbcode.php b/phpBB/includes/bbcode.php index c3367fbd46..3addb54110 100644 --- a/phpBB/includes/bbcode.php +++ b/phpBB/includes/bbcode.php @@ -127,14 +127,15 @@ class bbcode */ function bbcode_cache_init() { - global $phpbb_root_path, $phpEx, $config, $user; + global $phpbb_root_path, $phpEx, $config, $user, $phpbb_extension_manager; if (empty($this->template_filename)) { $this->template_bitfield = new bitfield($user->theme['bbcode_bitfield']); $template_locator = new phpbb_template_locator(); - $template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $template_locator); + $template_path_provider = new phpbb_template_path_provider($phpbb_extension_manager); + $template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $template_locator, $template_path_provider); $template->set_template(); $template_locator->set_filenames(array('bbcode.html' => 'bbcode.html')); $this->template_filename = $template_locator->get_source_file_for_handle('bbcode.html'); diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php index b94957a85f..2a206af7a9 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -175,7 +175,7 @@ class messenger */ function template($template_file, $template_lang = '', $template_path = '') { - global $config, $phpbb_root_path, $phpEx, $user; + global $config, $phpbb_root_path, $phpEx, $user, $phpbb_extension_manager; if (!trim($template_file)) { @@ -194,7 +194,8 @@ class messenger if (!isset($this->tpl_msg[$template_lang . $template_file])) { $template_locator = new phpbb_template_locator(); - $this->tpl_msg[$template_lang . $template_file] = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $template_locator); + $template_path_provider = new phpbb_template_path_provider($phpbb_extension_manager); + $this->tpl_msg[$template_lang . $template_file] = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $template_locator, $template_path_provider); $tpl = &$this->tpl_msg[$template_lang . $template_file]; $fallback_template_path = false; diff --git a/phpBB/includes/template/locator.php b/phpBB/includes/template/locator.php index 35e33bb9e6..44cd2cd7b9 100644 --- a/phpBB/includes/template/locator.php +++ b/phpBB/includes/template/locator.php @@ -28,62 +28,70 @@ if (!defined('IN_PHPBB')) class phpbb_template_locator { /** - * @var string Path to directory that templates are stored in. + * Paths to directories that templates are stored in. + * @var array */ - private $root = ''; + private $roots = array(); /** - * @var string Path to parent/fallback template directory. + * Index of the main template in the roots array + * @var int */ - private $inherit_root = ''; + private $main_root_id = 0; /** - * @var array Map from handles to source template file paths. + * Map from root index to handles to source template file paths. * Normally it only contains paths for handles that are used * (or are likely to be used) by the page being rendered and not * all templates that exist on the filesystem. + * @var array */ private $files = array(); /** - * @var array Map from handles to source template file names. + * Map from handles to source template file names. * Covers the same data as $files property but maps to basenames * instead of paths. + * @var array */ private $filenames = array(); /** - * @var array Map from handles to parent/fallback source template - * file paths. Covers the same data as $files. + * Set main template location (must have been added through set_paths first). + * + * @param string $template_path Path to template directory + * @return null */ - private $files_inherit = array(); + public function set_main_template($template) + { + $this->main_root_id = array_search($template, $this->roots, true); + } /** - * Set custom template location (able to use directory outside of phpBB). + * Sets the list of template paths * - * Note: Templates are still compiled to phpBB's cache directory. + * These paths will be searched for template files in the provided order. + * Paths may be outside of phpBB, but will still be cached to phpBB cache + * directory. * - * @param string $template_path Path to template directory - * @param string|bool $fallback_template_path Path to fallback template, or false to disable fallback + * @param array $template_paths An array of paths to template directories + * @return null */ - public function set_custom_template($template_path, $fallback_template_path = false) + public function set_paths($template_paths) { - // Make sure $template_path has no ending slash - if (substr($template_path, -1) == '/') - { - $template_path = substr($template_path, 0, -1); - } - - $this->root = $template_path; + $this->roots = array(); + $this->files = array(); + $this->filenames = array(); + $this->main_root_id = 0; - if ($fallback_template_path !== false) + foreach ($template_paths as $path) { - if (substr($fallback_template_path, -1) == '/') + // Make sure $path has no ending slash + if (substr($path, -1) === '/') { - $fallback_template_path = substr($fallback_template_path, 0, -1); + $path = substr($path, 0, -1); } - - $this->inherit_root = $fallback_template_path; + $this->roots[] = $path; } } @@ -103,11 +111,10 @@ class phpbb_template_locator } $this->filename[$handle] = $filename; - $this->files[$handle] = $this->root . '/' . $filename; - if ($this->inherit_root) + foreach ($this->roots as $root_index => $root) { - $this->files_inherit[$handle] = $this->inherit_root . '/' . $filename; + $this->files[$root_index][$handle] = $root . '/' . $filename; } } } @@ -154,12 +161,12 @@ class phpbb_template_locator public function get_virtual_source_file_for_handle($handle) { // If we don't have a file assigned to this handle, die. - if (!isset($this->files[$handle])) + if (!isset($this->files[$this->main_root_id][$handle])) { trigger_error("template locator: No file specified for handle $handle", E_USER_ERROR); } - $source_file = $this->files[$handle]; + $source_file = $this->files[$this->main_root_id][$handle]; return $source_file; } @@ -182,30 +189,26 @@ class phpbb_template_locator public function get_source_file_for_handle($handle) { // If we don't have a file assigned to this handle, die. - if (!isset($this->files[$handle])) + if (!isset($this->files[$this->main_root_id][$handle])) { trigger_error("template locator: No file specified for handle $handle", E_USER_ERROR); } - $source_file = $this->files[$handle]; + // locate a source file that exists + $source_file = $this->files[0][$handle]; + $tried = $source_file; + for ($i = 1, $n = count($this->roots); $i < $n && !file_exists($source_file); $i++) + { + $source_file = $this->files[$i][$handle]; + $tried .= ', ' . $source_file; + } - // Try and open template for reading + // search failed if (!file_exists($source_file)) { - if (isset($this->files_inherit[$handle]) && $this->files_inherit[$handle]) - { - $parent_source_file = $this->files_inherit[$handle]; - if (!file_exists($parent_source_file)) - { - trigger_error("template locator: Neither $source_file nor $parent_source_file exist", E_USER_ERROR); - } - $source_file = $parent_source_file; - } - else - { - trigger_error("template locator: File $source_file does not exist", E_USER_ERROR); - } + trigger_error("template locator: File for handle $handle does not exist. Could not find: $tried", E_USER_ERROR); } + return $source_file; } } diff --git a/phpBB/includes/template/path_provider.php b/phpBB/includes/template/path_provider.php new file mode 100644 index 0000000000..02d48cbea5 --- /dev/null +++ b/phpBB/includes/template/path_provider.php @@ -0,0 +1,137 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2011 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* Provides a template locator with paths +* +* Finds installed template paths and makes them available to the locator. +* +* @package phpBB3 +*/ +class phpbb_template_path_provider extends phpbb_extension_provider +{ + protected $main_template_name = ''; + protected $templates = array(); + protected $ext_dir_prefix = ''; + + /** + * Constructor stores extension manager + * + * @param phpbb_extension_manager $extension_manager phpBB extension manager + */ + public function __construct(phpbb_extension_manager $extension_manager) + { + // no super call to avoid find() call + $this->extension_manager = $extension_manager; + } + + /** + * Defines a prefix to use for template paths in extensions + * + * @param string $ext_dir_prefix The prefix including trailing slash + * @return null + */ + public function set_ext_dir_prefix($ext_dir_prefix) + { + $this->ext_dir_prefix = $ext_dir_prefix; + } + + /** + * Finds template paths using the extension manager + * + * Finds paths with the same name (e.g. styles/prosilver/template/) in all + * active extensions. Then appends the actual template paths based in the + * current working directory. + * + * @return array List of template paths + */ + public function find() + { + $finder = $this->extension_manager->get_finder(); + + $directories = array(); + + foreach ($this->templates as $name => $path) + { + if ($path && !phpbb_is_absolute($path)) + { + $directories = array_merge($directories, $finder + ->directory('/' . $this->ext_dir_prefix . $path) + ->get_directories() + ); + } + } + + foreach ($this->templates as $name => $path) + { + $directories[] = $path; + } + + return $directories; + } + + /** + * Overwrites the current template names and paths + * + * @param array $templates An associative map from template names to paths. + * The first element is the main template. + * If the path is false, it will be generated from + * the supplied name. + * @return null + */ + public function set_templates(array $templates) + { + $this->templates = array(); + + foreach ($templates as $name => $path) + { + if (!$path) + { + $path = $this->template_root_for_style($name); + } + + $this->templates[$name] = $path; + } + + reset($this->templates); + $this->main_template_path = current($this->templates); + + $this->items = $this->find(); + } + + /** + * Retrieves the path to the main template passed into set_templates() + * + * @return string Main template path + */ + public function get_main_template_path() + { + return $this->main_template_path; + } + + /** + * Converts a style name to relative (to board root or extension) path to + * the style's template files. + * + * @param $style_name string Style name + * @return string Path to style template files + */ + private function template_root_for_style($style_name) + { + return 'styles/' . $style_name . '/template'; + } +} diff --git a/phpBB/includes/template/template.php b/phpBB/includes/template/template.php index ec5fbe2829..53db171a5d 100644 --- a/phpBB/includes/template/template.php +++ b/phpBB/includes/template/template.php @@ -63,24 +63,33 @@ class phpbb_template private $user; /** - * @var locator template locator + * Template locator + * @var phpbb_template_locator */ private $locator; /** + * Template path provider + * @var phpbb_template_path_provider + */ + private $provider; + + /** * Constructor. * * @param string $phpbb_root_path phpBB root path * @param user $user current user * @param phpbb_template_locator $locator template locator + * @param phpbb_template_path_provider $provider template path provider */ - public function __construct($phpbb_root_path, $phpEx, $config, $user, phpbb_template_locator $locator) + public function __construct($phpbb_root_path, $phpEx, $config, $user, phpbb_template_locator $locator, phpbb_template_path_provider $provider) { $this->phpbb_root_path = $phpbb_root_path; $this->phpEx = $phpEx; $this->config = $config; $this->user = $user; $this->locator = $locator; + $this->provider = $provider; } /** @@ -88,25 +97,21 @@ class phpbb_template */ public function set_template() { - $style_name = $this->user->theme['template_path']; - - $relative_template_root = $this->relative_template_root_for_style($style_name); - $template_root = $this->phpbb_root_path . $relative_template_root; - if (!file_exists($template_root)) - { - trigger_error('template locator: Template path could not be found: ' . $relative_template_root, E_USER_ERROR); - } + $template_name = $this->user->theme['template_path']; + $fallback_name = ($this->user->theme['template_inherits_id']) ? $this->user->theme['template_inherit_path'] : false; - if ($this->user->theme['template_inherits_id']) - { - $fallback_template_path = $this->phpbb_root_path . $this->relative_template_root_for_style($this->user->theme['template_inherit_path']); - } - else - { - $fallback_template_path = null; - } + return $this->set_custom_template(false, $template_name, false, $fallback_name); + } - return $this->set_custom_template($template_root, $style_name, $fallback_template_path); + /** + * Defines a prefix to use for template paths in extensions + * + * @param string $ext_dir_prefix The prefix including trailing slash + * @return null + */ + public function set_ext_dir_prefix($ext_dir_prefix) + { + $this->provider->set_ext_dir_prefix($ext_dir_prefix); } /** @@ -117,12 +122,18 @@ class phpbb_template * @param string $template_path Path to template directory * @param string $template_name Name of template * @param string $fallback_template_path Path to fallback template + * @param string $fallback_template_name Name of fallback template */ - public function set_custom_template($template_path, $style_name, $fallback_template_path = false) + public function set_custom_template($template_path, $template_name, $fallback_template_path = false, $fallback_template_name = false) { - $this->locator->set_custom_template($template_path, $fallback_template_path); + $this->provider->set_templates(array( + $template_name => $template_path, + $fallback_template_name => $fallback_template_path, + )); + $this->locator->set_paths($this->provider); + $this->locator->set_main_template($this->provider->get_main_template_path()); - $this->cachepath = $this->phpbb_root_path . 'cache/tpl_' . str_replace('_', '-', $style_name) . '_'; + $this->cachepath = $this->phpbb_root_path . 'cache/tpl_' . str_replace('_', '-', $template_name) . '_'; $this->context = new phpbb_template_context(); @@ -130,18 +141,6 @@ class phpbb_template } /** - * Converts a style name to relative (to board root) path to - * the style's template files. - * - * @param $style_name string Style name - * @return string Path to style template files - */ - private function relative_template_root_for_style($style_name) - { - return 'styles/' . $style_name . '/template'; - } - - /** * Sets the template filenames for handles. * * @param array $filname_array Should be a hash of handle => filename pairs. diff --git a/phpBB/install/index.php b/phpBB/install/index.php index 0a46a06664..93effc27f1 100644 --- a/phpBB/install/index.php +++ b/phpBB/install/index.php @@ -202,8 +202,10 @@ $config = new phpbb_config(array( 'load_tplcompile' => '1' )); -$template_locator = new phpbb_template_locator(); -$template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $template_locator); +$phpbb_template_locator = new phpbb_template_locator(); +$phpbb_template_path_provider = new phpbb_template_path_provider($phpbb_extension_manager); +$template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $phpbb_template_locator, $phpbb_template_path_provider); +$template->set_ext_dir_prefix('adm/'); $template->set_custom_template('../adm/style', 'admin'); $template->assign_var('T_ASSETS_PATH', '../assets'); $template->assign_var('T_TEMPLATE_PATH', '../adm/style'); |