mirror of
https://github.com/moodle/moodle.git
synced 2025-04-15 05:25:08 +02:00
MDL-73679 core: Add a named_templatable interface
This interface allows a templatable to provide a template name via the 'get_template_name(): string' function and have it automatically rendered via a standard 'render()' call.
This commit is contained in:
parent
af0e3bcadc
commit
b43d729c85
37
lib/classes/output/named_templatable.php
Normal file
37
lib/classes/output/named_templatable.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace core\output;
|
||||
|
||||
use templatable;
|
||||
|
||||
/**
|
||||
* A subset of templatable which provides the name of the template to use.
|
||||
*
|
||||
* @package core
|
||||
* @copyright 2022 Andrew Lyons <andrew@nicols.co.uk>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
interface named_templatable extends templatable {
|
||||
|
||||
/**
|
||||
* Get the name of the template to use for this templatable.
|
||||
*
|
||||
* @param \renderer_base $renderer The renderer requesting the template name
|
||||
* @return string
|
||||
*/
|
||||
public function get_template_name(\renderer_base $renderer): string;
|
||||
}
|
@ -35,6 +35,7 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
use core\output\named_templatable;
|
||||
use core_completion\cm_completion_details;
|
||||
use core_course\output\activity_information;
|
||||
|
||||
@ -227,14 +228,29 @@ class renderer_base {
|
||||
$classparts = explode('\\', get_class($widget));
|
||||
// Strip namespaces.
|
||||
$classname = array_pop($classparts);
|
||||
// Remove _renderable suffixes
|
||||
// Remove _renderable suffixes.
|
||||
$classname = preg_replace('/_renderable$/', '', $classname);
|
||||
|
||||
$rendermethod = 'render_'.$classname;
|
||||
$rendermethod = "render_{$classname}";
|
||||
if (method_exists($this, $rendermethod)) {
|
||||
// Call the render_[widget_name] function.
|
||||
// Note: This has a higher priority than the named_templatable to allow the theme to override the template.
|
||||
return $this->$rendermethod($widget);
|
||||
}
|
||||
|
||||
if ($widget instanceof named_templatable) {
|
||||
// This is a named templatable.
|
||||
// Fetch the template name from the get_template_name function instead.
|
||||
// Note: This has higher priority than the guessed template name.
|
||||
return $this->render_from_template(
|
||||
$widget->get_template_name($this),
|
||||
$widget->export_for_template($this)
|
||||
);
|
||||
}
|
||||
|
||||
if ($widget instanceof templatable) {
|
||||
// Guess the templat ename based on the class name.
|
||||
// Note: There's no benefit to moving this aboved the named_templatable and this approach is more costly.
|
||||
$component = array_shift($classparts);
|
||||
if (!$component) {
|
||||
$component = 'core';
|
||||
@ -243,7 +259,7 @@ class renderer_base {
|
||||
$context = $widget->export_for_template($this);
|
||||
return $this->render_from_template($template, $context);
|
||||
}
|
||||
throw new coding_exception('Can not render widget, renderer method ('.$rendermethod.') not found.');
|
||||
throw new coding_exception("Can not render widget, renderer method ('{$rendermethod}') not found.");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -455,17 +471,33 @@ class plugin_renderer_base extends renderer_base {
|
||||
*/
|
||||
public function render(renderable $widget) {
|
||||
$classname = get_class($widget);
|
||||
|
||||
// Strip namespaces.
|
||||
$classname = preg_replace('/^.*\\\/', '', $classname);
|
||||
// Keep a copy at this point, we may need to look for a deprecated method.
|
||||
$deprecatedmethod = 'render_'.$classname;
|
||||
// Remove _renderable suffixes
|
||||
$classname = preg_replace('/_renderable$/', '', $classname);
|
||||
|
||||
$rendermethod = 'render_'.$classname;
|
||||
// Keep a copy at this point, we may need to look for a deprecated method.
|
||||
$deprecatedmethod = "render_{$classname}";
|
||||
|
||||
// Remove _renderable suffixes.
|
||||
$classname = preg_replace('/_renderable$/', '', $classname);
|
||||
$rendermethod = "render_{$classname}";
|
||||
|
||||
if (method_exists($this, $rendermethod)) {
|
||||
// Call the render_[widget_name] function.
|
||||
// Note: This has a higher priority than the named_templatable to allow the theme to override the template.
|
||||
return $this->$rendermethod($widget);
|
||||
}
|
||||
|
||||
if ($widget instanceof named_templatable) {
|
||||
// This is a named templatable.
|
||||
// Fetch the template name from the get_template_name function instead.
|
||||
// Note: This has higher priority than the deprecated method which is not overridable by themes anyway.
|
||||
return $this->render_from_template(
|
||||
$widget->get_template_name($this),
|
||||
$widget->export_for_template($this)
|
||||
);
|
||||
}
|
||||
|
||||
if ($rendermethod !== $deprecatedmethod && method_exists($this, $deprecatedmethod)) {
|
||||
// This is exactly where we don't want to be.
|
||||
// If you have arrived here you have a renderable component within your plugin that has the name
|
||||
@ -475,15 +507,20 @@ class plugin_renderer_base extends renderer_base {
|
||||
// You need to change your renderers render_blah_renderable to render_blah.
|
||||
// Until you do this it will not be possible for a theme to override the renderer to override your method.
|
||||
// Please do it ASAP.
|
||||
static $debugged = array();
|
||||
static $debugged = [];
|
||||
if (!isset($debugged[$deprecatedmethod])) {
|
||||
debugging(sprintf('Deprecated call. Please rename your renderables render method from %s to %s.',
|
||||
$deprecatedmethod, $rendermethod), DEBUG_DEVELOPER);
|
||||
debugging(sprintf(
|
||||
'Deprecated call. Please rename your renderables render method from %s to %s.',
|
||||
$deprecatedmethod,
|
||||
$rendermethod
|
||||
), DEBUG_DEVELOPER);
|
||||
$debugged[$deprecatedmethod] = true;
|
||||
}
|
||||
return $this->$deprecatedmethod($widget);
|
||||
}
|
||||
// pass to core renderer if method not found here
|
||||
|
||||
// Pass to core renderer if method not found here.
|
||||
// Note: this is not a parent. This is _new_ renderer which respects the requested format, and output type.
|
||||
return $this->output->render($widget);
|
||||
}
|
||||
|
||||
|
@ -233,6 +233,9 @@ value to get the list of blocks that won't be displayed for a theme.
|
||||
$strength passed to it.
|
||||
* A new method get_page() has been added to the settings_navigation class. This method can be used to obtain the
|
||||
moodle_page object associated to the settings navigation.
|
||||
* A new interface, `core\output\named_templatable` has been created to allow renderable classes to define a
|
||||
`get_template_name(\renderer_base): string` function which will inform the default render() function with a template
|
||||
name.
|
||||
|
||||
=== 3.11.4 ===
|
||||
* A new option dontforcesvgdownload has been added to the $options parameter of the send_file() function.
|
||||
|
Loading…
x
Reference in New Issue
Block a user