mirror of
https://github.com/moodle/moodle.git
synced 2025-04-16 05:54:19 +02:00
MDL-78207 course: Add new module badges feature
The new activity card design proposed for Moodle 4.3 differentiates badge information from other HTML content (displayed using the afterlink feature). This commit adds a new activitybadge class that can be extended by any module to display any content in a badge near the activity name. These are the main features: - The badge content is always plain text (no HTML). - The badge style can be set (by default is initialized with badge-none, but it can be set by any module). - An optional URL to redirect the user when the badge is clicked. - An optional ID to add the element in case the module wants to add some JS to the badge events. - Optionally, any other extra HTML attributes to the badge element (for example, data attributes).
This commit is contained in:
parent
b6849bd973
commit
6db715f5c3
@ -28,6 +28,7 @@ defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
use core_course\external\course_summary_exporter;
|
||||
use core_external\external_api;
|
||||
use core_external\external_description;
|
||||
use core_external\external_files;
|
||||
use core_external\external_format_value;
|
||||
use core_external\external_function_parameters;
|
||||
@ -268,6 +269,10 @@ class core_course_external extends external_api {
|
||||
$module['indent'] = $cm->indent;
|
||||
$module['onclick'] = $cm->onclick;
|
||||
$module['afterlink'] = $cm->afterlink;
|
||||
$activitybadgedata = $cm->get_activitybadge();
|
||||
if (!empty($activitybadgedata)) {
|
||||
$module['activitybadge'] = $activitybadgedata;
|
||||
}
|
||||
$module['customdata'] = json_encode($cm->customdata);
|
||||
$module['completion'] = $cm->completion;
|
||||
$module['downloadcontent'] = $cm->downloadcontent;
|
||||
@ -461,6 +466,7 @@ class core_course_external extends external_api {
|
||||
'onclick' => new external_value(PARAM_RAW, 'Onclick action.', VALUE_OPTIONAL),
|
||||
'afterlink' => new external_value(PARAM_RAW, 'After link info to be displayed.',
|
||||
VALUE_OPTIONAL),
|
||||
'activitybadge' => self::get_activitybadge_structure(),
|
||||
'customdata' => new external_value(PARAM_RAW, 'Custom data (JSON encoded).', VALUE_OPTIONAL),
|
||||
'noviewlink' => new external_value(PARAM_BOOL, 'Whether the module has no view page',
|
||||
VALUE_OPTIONAL),
|
||||
@ -533,6 +539,60 @@ class core_course_external extends external_api {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of activitybadge data.
|
||||
*
|
||||
* @return external_description
|
||||
*/
|
||||
protected static function get_activitybadge_structure(): external_description {
|
||||
return new external_single_structure(
|
||||
[
|
||||
'badgecontent' => new external_value(
|
||||
PARAM_TEXT,
|
||||
'The content to be displayed in the activity badge',
|
||||
VALUE_OPTIONAL
|
||||
),
|
||||
'badgestyle' => new external_value(
|
||||
PARAM_TEXT,
|
||||
'The style for the activity badge',
|
||||
VALUE_OPTIONAL
|
||||
),
|
||||
'badgeurl' => new external_value(
|
||||
PARAM_URL,
|
||||
'An optional URL to redirect the user when the activity badge is clicked',
|
||||
VALUE_OPTIONAL
|
||||
),
|
||||
'badgeelementid' => new external_value(
|
||||
PARAM_ALPHANUMEXT,
|
||||
'An optional id in case the module wants to add some code for the activity badge',
|
||||
VALUE_OPTIONAL
|
||||
),
|
||||
'badgeextraattributes' => new external_multiple_structure(
|
||||
new external_single_structure(
|
||||
[
|
||||
'name' => new external_value(
|
||||
PARAM_TEXT,
|
||||
'The attribute name',
|
||||
VALUE_OPTIONAL
|
||||
),
|
||||
'value' => new external_value(
|
||||
PARAM_TEXT,
|
||||
'The attribute value',
|
||||
VALUE_OPTIONAL
|
||||
),
|
||||
],
|
||||
'Each of the attribute names and values',
|
||||
VALUE_OPTIONAL
|
||||
),
|
||||
'An optional array of extra HTML attributes to add to the badge element',
|
||||
VALUE_OPTIONAL
|
||||
),
|
||||
],
|
||||
'Activity badge to display near the name',
|
||||
VALUE_OPTIONAL
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method parameters
|
||||
*
|
||||
|
129
course/format/classes/output/activitybadge.php
Normal file
129
course/format/classes/output/activitybadge.php
Normal file
@ -0,0 +1,129 @@
|
||||
<?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_courseformat\output;
|
||||
|
||||
use cm_info;
|
||||
use core_courseformat\output\local\courseformat_named_templatable;
|
||||
use core\output\named_templatable;
|
||||
use renderer_base;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Base class to render an activity badge.
|
||||
*
|
||||
* Plugins can extend this class and override some methods to customize the content to be displayed in the activity badge.
|
||||
*
|
||||
* @package core_courseformat
|
||||
* @copyright 2023 Sara Arjona <sara@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
abstract class activitybadge implements named_templatable, \renderable {
|
||||
use courseformat_named_templatable;
|
||||
|
||||
/** @var array Badge defined styles. */
|
||||
public const STYLES = [
|
||||
'none' => 'badge-none',
|
||||
'dark' => 'badge-dark',
|
||||
'danger' => 'badge-danger',
|
||||
'warning' => 'badge-warning',
|
||||
'info' => 'badge-info',
|
||||
];
|
||||
|
||||
/** @var cm_info The course module information. */
|
||||
protected $cminfo = null;
|
||||
|
||||
/** @var string The content to be displayed in the activity badge. */
|
||||
protected $content = null;
|
||||
|
||||
/** @var string The style for the activity badge. */
|
||||
protected $style = self::STYLES['none'];
|
||||
|
||||
/** @var \moodle_url An optional URL to redirect the user when the activity badge is clicked. */
|
||||
protected $url = null;
|
||||
|
||||
/** @var string An optional element id in case the module wants to add some code for the activity badge (events, CSS...). */
|
||||
protected $elementid = null;
|
||||
|
||||
/**
|
||||
* @var array An optional array of extra HTML attributes to add to the badge element (for example, data attributes).
|
||||
* The format for this array is [['name' => 'attr1', 'value' => 'attrval1'], ['name' => 'attr2', 'value' => 'attrval2']].
|
||||
*/
|
||||
protected $extraattributes = [];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param cm_info $cminfo The course module information.
|
||||
*/
|
||||
public function __construct(cm_info $cminfo) {
|
||||
$this->cminfo = $cminfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export this data so it can be used as the context for a mustache template.
|
||||
*
|
||||
* @param renderer_base $output typically, the renderer that's calling this function
|
||||
* @return stdClass data context for a mustache template
|
||||
*/
|
||||
final public function export_for_template(renderer_base $output): stdClass {
|
||||
$this->update_content();
|
||||
if (empty($this->content)) {
|
||||
return new stdClass();
|
||||
}
|
||||
|
||||
$data = (object)[
|
||||
'badgecontent' => $this->content,
|
||||
'badgestyle' => $this->style,
|
||||
];
|
||||
|
||||
if (!empty($this->url)) {
|
||||
$data->badgeurl = $this->url->out();
|
||||
}
|
||||
|
||||
if (!empty($this->elementid)) {
|
||||
$data->badgeelementid = $this->elementid;
|
||||
}
|
||||
|
||||
if (!empty($this->extraattributes)) {
|
||||
$data->badgeextraattributes = $this->extraattributes;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of activityclass for the given course module, in case it implements it.
|
||||
*
|
||||
* @param cm_info $cminfo
|
||||
* @return self|null An instance of activityclass for the given module or null if the module doesn't implement it.
|
||||
*/
|
||||
final public static function create_instance(cm_info $cminfo): ?self {
|
||||
$classname = '\mod_' . $cminfo->modname . '\output\courseformat\activitybadge';
|
||||
if (!class_exists($classname)) {
|
||||
return null;
|
||||
}
|
||||
return new $classname($cminfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will be called before exporting the template.
|
||||
*
|
||||
* It should be implemented by any module extending this class and will be in charge of updating any of the class attributes
|
||||
* with the proper information that will be displayed in the activity badge (like the content or the badge style).
|
||||
*/
|
||||
abstract protected function update_content(): void;
|
||||
}
|
@ -31,6 +31,7 @@ use core_availability\info_module;
|
||||
use core_completion\cm_completion_details;
|
||||
use core_course\output\activity_information;
|
||||
use core_courseformat\base as course_format;
|
||||
use core_courseformat\output\activitybadge;
|
||||
use core_courseformat\output\local\courseformat_named_templatable;
|
||||
use renderable;
|
||||
use renderer_base;
|
||||
@ -186,6 +187,12 @@ class cm implements named_templatable, renderable {
|
||||
);
|
||||
$data->altcontent = (empty($altcontent)) ? false : $altcontent;
|
||||
$data->afterlink = $this->mod->afterlink;
|
||||
|
||||
$activitybadgedata = $this->mod->get_activitybadge($output);
|
||||
if (!empty($activitybadgedata)) {
|
||||
$data->activitybadge = $activitybadgedata;
|
||||
}
|
||||
|
||||
return !empty($data->altcontent);
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,23 @@
|
||||
"displayvalue" : "<a class=\"aalink\" href=\"#\"><span class=\"instancename\">Activity example</span></a>"
|
||||
},
|
||||
"hasname": "true",
|
||||
"afterlink": "<span class=\"badge badge-primary\">30 unread messages</span>",
|
||||
"afterlink": "<span class=\"resourcelinkdetails\">24.7 KB · Uploaded 26/05/23, 16:29</span>",
|
||||
"activitybadge": {
|
||||
"badgecontent": "PDF",
|
||||
"badgestyle": "badge-none",
|
||||
"badgeurl": "http://example.org/help",
|
||||
"badgeelementid": "myelementid",
|
||||
"badgeextraattributes": [
|
||||
{
|
||||
"name": "data-el1name",
|
||||
"value": "el1value"
|
||||
},
|
||||
{
|
||||
"name": "data-el2name",
|
||||
"value": "el2value"
|
||||
}
|
||||
]
|
||||
},
|
||||
"hasextras": true,
|
||||
"extras": ["<span class=\"badge badge-secondary\">[extras]</span>"],
|
||||
"activityinfo": {
|
||||
@ -69,6 +85,13 @@
|
||||
{{> core_courseformat/local/content/cm/cmname }}
|
||||
{{/ core_courseformat/local/content/cm/cmname }}
|
||||
{{/cmname}}
|
||||
|
||||
{{#activitybadge}}
|
||||
{{$ core_courseformat/local/content/cm/activitybadge }}
|
||||
{{> core_courseformat/local/content/cm/activitybadge }}
|
||||
{{/ core_courseformat/local/content/cm/activitybadge }}
|
||||
{{/activitybadge}}
|
||||
|
||||
{{#activityinfo}}
|
||||
<div class="activity-info mt-1 mt-md-0">
|
||||
{{$ core_courseformat/local/content/cm/activity_info}}
|
||||
|
@ -0,0 +1,55 @@
|
||||
{{!
|
||||
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/>.
|
||||
}}
|
||||
{{!
|
||||
@template core_courseformat/local/content/cm/activitybadge
|
||||
|
||||
Container to display activity badge information such as:
|
||||
- Unread messages for forums
|
||||
- File types for resources
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"badgecontent": "PDF",
|
||||
"badgestyle": "badge-none",
|
||||
"badgeurl": "http://example.org/help",
|
||||
"badgeelementid": "myelementid",
|
||||
"badgeextraattributes": [
|
||||
{
|
||||
"name": "data-el1name",
|
||||
"value": "el1value"
|
||||
},
|
||||
{
|
||||
"name": "data-el2name",
|
||||
"value": "el2value"
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
<div
|
||||
{{#badgeelementid}}id="{{.}}"{{/badgeelementid}}
|
||||
class="m-2 d-flex align-items-center"
|
||||
{{#badgeextraattributes}} {{name}}="{{value}}" {{/badgeextraattributes}}
|
||||
>
|
||||
<div class="activitybadge badge badge-pill {{badgestyle}}">
|
||||
{{#badgeurl}}
|
||||
<a href="{{.}}">{{badgecontent}}</a>
|
||||
{{/badgeurl}}
|
||||
{{^badgeurl}}
|
||||
{{badgecontent}}
|
||||
{{/badgeurl}}
|
||||
</div>
|
||||
</div>
|
@ -2,6 +2,17 @@ This files describes API changes for course formats
|
||||
|
||||
Overview of this plugin type at http://docs.moodle.org/dev/Course_formats
|
||||
|
||||
=== 4.3 ===
|
||||
* New core_courseformat\output\activitybadge class that can be extended by any module to display content near the activity name.
|
||||
The content of the afterlink feature has been moved to the end of the activity card so modules using it should check this new
|
||||
feature which might fit better.
|
||||
Some considerations about the activitybadge feature:
|
||||
- The badge content is always plain text (no HTML).
|
||||
- The badge style can be set (by default is initialized with badge-none, but it can be set by any module).
|
||||
- An optional URL to redirect the user when the badge is clicked.
|
||||
- An optional ID to add the element in case the module wants to add some JS to the badge events.
|
||||
- Optionally, any other extra HTML attributes to the badge element (for example, data attributes).
|
||||
|
||||
=== 4.2 ===
|
||||
* New core_courseformat\base::get_context() to get the course context directly from the format instance.
|
||||
* New core_courseformat\base::delete_module() method. Now format plugins can extend the activity deletion logic
|
||||
|
@ -3,6 +3,8 @@ information provided here is intended especially for developers.
|
||||
|
||||
=== 4.3 ===
|
||||
* The `core_course_renderer::course_section_cm_completion` method has been removed, and can no longer be used
|
||||
* External function core_course_external::get_course_contents() now returns a new field activitybadge with the data to display
|
||||
the activity badge when the module implements it.
|
||||
|
||||
=== 4.2 ===
|
||||
* course/mod.php now accepts parameter beforemod for adding course modules. It contains the course module id
|
||||
|
@ -32,6 +32,7 @@ if (!defined('MAX_MODINFO_CACHE_SIZE')) {
|
||||
define('MAX_MODINFO_CACHE_SIZE', 10);
|
||||
}
|
||||
|
||||
use core_courseformat\output\activitybadge;
|
||||
|
||||
/**
|
||||
* Information about a course that is cached in the course table 'modinfo' field (and then in
|
||||
@ -1756,6 +1757,28 @@ class cm_info implements IteratorAggregate {
|
||||
return $this->afterlink;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the activity badge data associated to this course module (if the module supports it).
|
||||
* Modules can use this method to provide additional data to be displayed in the activity badge.
|
||||
*
|
||||
* @param renderer_base $output Output render to use, or null for default (global)
|
||||
* @return stdClass|null The activitybadge data (badgecontent, badgestyle...) or null if the module doesn't implement it.
|
||||
*/
|
||||
public function get_activitybadge(?renderer_base $output = null): ?stdClass {
|
||||
global $OUTPUT;
|
||||
|
||||
$activibybadgeclass = activitybadge::create_instance($this);
|
||||
if (empty($activibybadgeclass)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!isset($output)) {
|
||||
$output = $OUTPUT;
|
||||
}
|
||||
|
||||
return $activibybadgeclass->export_for_template($output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: Will collect view data, if not already obtained.
|
||||
* @return string Extra HTML code to display after editing icons (e.g. more icons)
|
||||
|
Loading…
x
Reference in New Issue
Block a user