From c927e35c4864c80eb1db8ee440e40af26601afcb Mon Sep 17 00:00:00 2001 From: Petr Skoda Date: Thu, 17 Dec 2009 22:43:27 +0000 Subject: [PATCH] MDL-21148 geenral support for rendering targets, this should give us more flexibility; please propose improvements in the tracker if necessary, thanks --- lib/outputfactories.php | 117 +++++++++++++++++++---------- lib/outputlib.php | 11 +-- lib/outputrenderers.php | 23 ++++-- lib/pagelib.php | 5 +- theme/custom_corners/README.html | 2 +- theme/custom_corners/lib.php | 10 +-- theme/custom_corners/renderers.php | 2 +- webservice/renderer.php | 2 +- 8 files changed, 110 insertions(+), 62 deletions(-) diff --git a/lib/outputfactories.php b/lib/outputfactories.php index 9418c6dca9..6b4e78c2df 100644 --- a/lib/outputfactories.php +++ b/lib/outputfactories.php @@ -27,6 +27,21 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +/** General rendering target, usually normal browser page */ +define('RENDERER_TARGET_GENERAL', 'general'); + +/** Plain text rendering for CLI scripts and cron */ +define('RENDERER_TARGET_CLI', 'cli'); + +/** Plain text rendering intended for sending via email */ +define('RENDERER_TARGET_TEXTEMAIL', 'textemail'); + +/** Rich text html rendering intended for sending via email */ +define('RENDERER_TARGET_HTMLEMAIL', 'htmlemail'); + +/* note: maybe we could define portfolio export target too */ + + /** * A renderer factory is just responsible for creating an appropriate renderer * for any given part of Moodle. @@ -64,9 +79,10 @@ interface renderer_factory { * @param moodle_page $page the page the renderer is outputting content for. * @param string $component name such as 'core', 'mod_forum' or 'qtype_multichoice'. * @param string $subtype optional subtype such as 'news' resulting to 'mod_forum_news' + * @param string $target one of rendering target constants * @return object an object implementing the requested renderer interface. */ - public function get_renderer(moodle_page $page, $component, $subtype=null); + public function get_renderer(moodle_page $page, $component, $subtype=null, $target=null); } @@ -86,8 +102,9 @@ interface renderer_factory { abstract class renderer_factory_base implements renderer_factory { /** @var theme_config the theme we belong to. */ protected $theme; - /** @var hardcoded list of core subtypes and their locations */ - protected $core_subtypes = array('webservice'=>'webservice'); + + /** @var hardcoded list of core subtypes and their locations, add more if ßneeded */ + protected $core_subtypes = array('webservice' => 'webservice'); /** * Constructor. @@ -97,6 +114,27 @@ abstract class renderer_factory_base implements renderer_factory { $this->theme = $theme; } + /** + * Returns suffix of renderer class expected for given target. + * @param string $target one of the renderer target constants, target is guessed if null used + * @return array two element array, first element is target, second the target suffix string + */ + protected function get_target_suffix($target) { + if (empty($target) and CLI_SCRIPT) { + // automatically guessed default for all CLI scripts + $target = RENDERER_TARGET_CLI; + } + + switch ($target) { + case RENDERER_TARGET_CLI: $suffix = '_cli'; break; + case RENDERER_TARGET_TEXTEMAIL: $suffix = '_textemail'; break; + case RENDERER_TARGET_HTMLEMAIL: $suffix = '_htmlemail'; break; + default: $target = RENDERER_TARGET_GENERAL; $suffix = ''; + } + + return array($target, $suffix); + } + /** * For a given module name, return the name of the standard renderer class * that defines the renderer interface for that module. @@ -108,13 +146,13 @@ abstract class renderer_factory_base implements renderer_factory { * @param string $subtype optional subtype such as 'news' resulting to 'mod_forum_news' * @return string the name of the standard renderer class for that module. */ - protected function standard_renderer_classname($component, $subtype=null) { + protected function standard_renderer_classname($component, $subtype = null) { global $CFG; // needed in incldued files if ($component !== 'core') { // standardize component names if (strpos($component, '_') === false) { - $component = $component.'_mod'; + $component = 'mod_' . $component; } // renderers are stored in renderer.php files if (!$compdirectory = get_component_directory($component)) { @@ -127,7 +165,7 @@ abstract class renderer_factory_base implements renderer_factory { } else if (!empty($subtype)) { if (!isset($this->core_subtypes[$subtype])) { - throw new coding_exception('Invalid core subtype "'.$subtype.'" in renderer request'); + throw new coding_exception('Invalid core subtype "' . $subtype . '" in renderer request'); } $rendererfile = $CFG->dirroot . '/' . $this->core_subtypes[$subtype] . '/renderer.php'; if (file_exists($rendererfile)) { @@ -159,42 +197,23 @@ class standard_renderer_factory extends renderer_factory_base { * @param moodle_page $page the page the renderer is outputting content for. * @param string $component name such as 'core', 'mod_forum' or 'qtype_multichoice'. * @param string $subtype optional subtype such as 'news' resulting to 'mod_forum_news' + * @param string $target one of rendering target constants * @return object an object implementing the requested renderer interface. */ - public function get_renderer(moodle_page $page, $component, $subtype=null) { + public function get_renderer(moodle_page $page, $component, $subtype = null, $target = null) { $classname = $this->standard_renderer_classname($component, $subtype); if (!class_exists($classname)) { throw new coding_exception('Request for an unknown renderer class ' . $classname); } - return new $classname($page); - } -} - -/** - * This is a slight variation on the standard_renderer_factory used by CLI scripts. - * CLI renderers use suffic '_cli' added to the standard renderer names - * - * @copyright 2009 Tim Hunt - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - * @since Moodle 2.0 - */ -class cli_renderer_factory extends renderer_factory_base { - /** - * Implement the subclass method - * @param moodle_page $page the page the renderer is outputting content for. - * @param string $component name such as 'core', 'mod_forum' or 'qtype_multichoice'. - * @param string $subtype optional subtype such as 'news' resulting to 'mod_forum_news' - * @return object an object implementing the requested renderer interface. - */ - public function get_renderer(moodle_page $page, $component, $subtype=null) { - $classname = $this->standard_renderer_classname($component, $subtype); - if (class_exists($classname . '_cli')) { - $classname = $classname . '_cli'; - } else if (!class_exists($classname)) { - throw new coding_exception('Request for an unknown renderer class ' . $classname); + list($target, $suffix) = $this->get_target_suffix($target); + if (class_exists($classname . $suffix)) { + // use the specialised renderer for given target, default renderer might also decide + // to implement support for more targets + $classname = $classname . $suffix; } - return new $classname($page); + + return new $classname($page, $target); } } @@ -232,23 +251,43 @@ class theme_overridden_renderer_factory extends renderer_factory_base { * @param moodle_page $page the page the renderer is outputting content for. * @param string $component name such as 'core', 'mod_forum' or 'qtype_multichoice'. * @param string $subtype optional subtype such as 'news' resulting to 'mod_forum_news' + * @param string $target one of rendering target constants * @return object an object implementing the requested renderer interface. */ - public function get_renderer(moodle_page $page, $component, $subtype=null) { + public function get_renderer(moodle_page $page, $component, $subtype = null, $target = null) { $classname = $this->standard_renderer_classname($component, $subtype); if (!class_exists($classname)) { // standard renderer must always exist throw new coding_exception('Request for an unknown renderer class ' . $classname); } + list($target, $suffix) = $this->get_target_suffix($target); + + // theme lib.php and renderers.php files are loaded automatically + // when loading the theme configs + + // first try the renderers with correct suffix + foreach ($this->prefixes as $prefix) { + if (class_exists($prefix . '_' . $classname . $suffix)) { + $classname = $prefix . '_' . $classname . $suffix; + return new $classname($page, $target); + } + } + if (class_exists($classname . $suffix)) { + // use the specialised renderer for given target, default renderer might also decide + // to implement support for more targets + $classname = $classname . $suffix; + return new $classname($page, $target); + } + + // then try general renderer foreach ($this->prefixes as $prefix) { - // theme lib.php and renderers.php files are loaded automatically if (class_exists($prefix . '_' . $classname)) { $classname = $prefix . '_' . $classname; - return new $classname($page); + return new $classname($page, $target); } } - // use standard renderes if themes do not contain overridden renderer - return new $classname($page); + + return new $classname($page, $target); } } diff --git a/lib/outputlib.php b/lib/outputlib.php index 1ae80af150..7c712474a3 100644 --- a/lib/outputlib.php +++ b/lib/outputlib.php @@ -909,19 +909,16 @@ class theme_config { * @param moodle_page $page the page we are rendering * @param string $module the name of part of moodle. E.g. 'core', 'quiz', 'qtype_multichoice'. * @param string $subtype optional subtype such as 'news' resulting to 'mod_forum_news' + * @param string $target one of rendering target constants * @return renderer_base the requested renderer. */ - public function get_renderer(moodle_page $page, $component, $subtype=null) { + public function get_renderer(moodle_page $page, $component, $subtype = null, $target = null) { if (is_null($this->rf)) { - if (CLI_SCRIPT) { - $classname = 'cli_renderer_factory'; - } else { - $classname = $this->rendererfactory; - } + $classname = $this->rendererfactory; $this->rf = new $classname($this); } - return $this->rf->get_renderer($page, $component, $subtype); + return $this->rf->get_renderer($page, $component, $subtype, $target); } /** diff --git a/lib/outputrenderers.php b/lib/outputrenderers.php index 02ada10bba..15c2c98d60 100644 --- a/lib/outputrenderers.php +++ b/lib/outputrenderers.php @@ -42,14 +42,18 @@ class renderer_base { protected $opencontainers; /** @var moodle_page the page we are rendering for. */ protected $page; + /** @var requested rendering target conatnt */ + protected $target; /** * Constructor * @param moodle_page $page the page we are doing output for. + * @param string $target one of rendering target constants */ - public function __construct(moodle_page $page) { + public function __construct(moodle_page $page, $target) { $this->opencontainers = $page->opencontainers; $this->page = $page; + $this->target = $target; } /** @@ -156,7 +160,7 @@ class renderer_base { * @param string $component full plugin name * @return moodle_url */ - public function pix_url($imagename, $component='moodle') { + public function pix_url($imagename, $component = 'moodle') { return $this->page->theme->pix_url($imagename, $component); } @@ -202,10 +206,13 @@ class renderer_base { } } + /** * Basis for all plugin renderers. * - * @author Petr Škoda + * @author Petr Skoda (skodak) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.0 */ class plugin_renderer_base extends renderer_base { /** @@ -217,10 +224,11 @@ class plugin_renderer_base extends renderer_base { /** * Contructor method, calls the parent constructor * @param moodle_page $page + * @param string $target one of rendering target constants */ - public function __construct(moodle_page $page) { - $this->output = $page->get_renderer('core'); - parent::__construct($page); + public function __construct(moodle_page $page, $target) { + $this->output = $page->get_renderer('core', null, $target); + parent::__construct($page, $target); } /** @@ -230,6 +238,8 @@ class plugin_renderer_base extends renderer_base { * @param string $method * @param array $arguments * @return mixed + * + * TODO: this might not be the best idea, see MDL-21148 for pros&cons */ public function __call($method, $arguments) { if (method_exists($this->output, $method)) { @@ -240,6 +250,7 @@ class plugin_renderer_base extends renderer_base { } } + /** * The standard implementation of the core_renderer interface. * diff --git a/lib/pagelib.php b/lib/pagelib.php index df0a112a05..a7cd74a17a 100644 --- a/lib/pagelib.php +++ b/lib/pagelib.php @@ -524,10 +524,11 @@ class moodle_page { * Returns instance of page renderer * @param string $component name such as 'core', 'mod_forum' or 'qtype_multichoice'. * @param string $subtype optional subtype such as 'news' resulting to 'mod_forum_news' + * @param string $target one of rendering target constants * @return renderer_base */ - public function get_renderer($component, $subtype = null) { - return $this->magic_get_theme()->get_renderer($this, $component, $subtype); + public function get_renderer($component, $subtype = null, $target = null) { + return $this->magic_get_theme()->get_renderer($this, $component, $subtype, $target); } /** diff --git a/theme/custom_corners/README.html b/theme/custom_corners/README.html index 4c9f063328..6b27ed3bce 100644 --- a/theme/custom_corners/README.html +++ b/theme/custom_corners/README.html @@ -5,7 +5,7 @@ Roger Johansson - see "customising_custom_corners_and_borders" However, the custom corners theme doesn't use all the JavaScript mentioned by Roger Johansson. - Instead, divs are added when using the custom_corners_core_renderer (defined in renderers.php) instead of moodle_core renderer. + Instead, divs are added when using the custom_corners_core_renderer (defined in renderers.php) instead of core_renderer.

diff --git a/theme/custom_corners/lib.php b/theme/custom_corners/lib.php index 668880df28..abad4b3d03 100644 --- a/theme/custom_corners/lib.php +++ b/theme/custom_corners/lib.php @@ -2,7 +2,7 @@ /** * This is a slight variatoin on the standard_renderer_factory that uses - * custom_corners_core_renderer instead of moodle_core_renderer. + * custom_corners_core_renderer instead of core_renderer. * * This generates the slightly different HTML that the custom_corners theme expects. * @@ -18,10 +18,10 @@ class custom_corners_renderer_factory extends standard_renderer_factory { } /* Implement the subclass method. */ - public function get_renderer(moodle_page $page, $module, $subtype=null) { - if ($module == 'core') { - return new custom_corners_core_renderer($page); + public function get_renderer(moodle_page $page, $component, $subtype = null, $target = null) { + if ($component == 'core' and empty($subtype)) { + return new custom_corners_core_renderer($page, $target); } - return parent::get_renderer($page, $module, $subtype); + return parent::get_renderer($page, $component, $subtype, $target); } } diff --git a/theme/custom_corners/renderers.php b/theme/custom_corners/renderers.php index c24239f64f..cabfb002e9 100644 --- a/theme/custom_corners/renderers.php +++ b/theme/custom_corners/renderers.php @@ -37,7 +37,7 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @since Moodle 2.0 */ -class custom_corners_core_renderer extends moodle_core_renderer { +class custom_corners_core_renderer extends core_renderer { protected $wraplevel = 1; protected function custom_corners_divs($classes = '', $idbase = '') { diff --git a/webservice/renderer.php b/webservice/renderer.php index c3a0876547..83dee9e85d 100644 --- a/webservice/renderer.php +++ b/webservice/renderer.php @@ -27,7 +27,7 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class core_wsdoc_renderer extends plugin_renderer_base { +class core_webservice_renderer extends plugin_renderer_base { /** * Create documentation for a description object * @param object $params a part of parameter/return description -- 2.39.5