mirror of
https://github.com/moodle/moodle.git
synced 2025-01-17 13:38:32 +01:00
MDL-78204 course: Use 'showmore' component in course restrictions
- Create new availability template, so it can be reused from both section/availability and cm/availability mustaches. - When rendering activity or section restrictions with long or multiline text display a condensed version (excerpt) and use 'showmore' component to add showmore/showless behaviour. Co-authored-by: Ferran Recio <ferran@moodle.com>
This commit is contained in:
parent
fb49de8875
commit
045f8cb50d
@ -44,6 +44,7 @@ Feature: Confirm that conditions on completion no longer cause a bug
|
|||||||
And I click on "Activity completion" "button" in the "Add restriction..." "dialogue"
|
And I click on "Activity completion" "button" in the "Add restriction..." "dialogue"
|
||||||
And I set the field with xpath "//div[contains(concat(' ', normalize-space(@class), ' '), ' availability-item ')][preceding-sibling::div]//select[@name='cm']" to "Page2"
|
And I set the field with xpath "//div[contains(concat(' ', normalize-space(@class), ' '), ' availability-item ')][preceding-sibling::div]//select[@name='cm']" to "Page2"
|
||||||
And I press "Save and return to course"
|
And I press "Save and return to course"
|
||||||
|
And I click on "Show more" "button" in the "#section-1 .availabilityinfo" "css_element"
|
||||||
Then I should see "Not available unless:" in the ".activity.glossary" "css_element"
|
Then I should see "Not available unless:" in the ".activity.glossary" "css_element"
|
||||||
And I should see "The activity Page1 is marked complete" in the ".activity.glossary" "css_element"
|
And I should see "The activity Page1 is marked complete" in the ".activity.glossary" "css_element"
|
||||||
And I should see "The activity Page2 is marked complete" in the ".activity.glossary" "css_element"
|
And I should see "The activity Page2 is marked complete" in the ".activity.glossary" "css_element"
|
||||||
|
@ -73,13 +73,17 @@ Feature: display_availability
|
|||||||
And I should see "2013" in the "#section-1 .availabilityinfo" "css_element"
|
And I should see "2013" in the "#section-1 .availabilityinfo" "css_element"
|
||||||
And I should see "2013" in the "#section-1 .availabilityinfo" "css_element"
|
And I should see "2013" in the "#section-1 .availabilityinfo" "css_element"
|
||||||
And "li" "css_element" should not exist in the "#section-1 .availabilityinfo" "css_element"
|
And "li" "css_element" should not exist in the "#section-1 .availabilityinfo" "css_element"
|
||||||
|
And "Show more" "button" should not exist in the "#section-1 .availabilityinfo" "css_element"
|
||||||
|
|
||||||
# Page 2 should show in list format.
|
# Page 2 should show in list format.
|
||||||
And "li" "css_element" should exist in the "#section-2 .availabilityinfo" "css_element"
|
And "li" "css_element" should exist in the "#section-2 .availabilityinfo" "css_element"
|
||||||
And I should see "Not available unless:" in the "#section-2 .availabilityinfo" "css_element"
|
And I should see "Not available unless:" in the "#section-2 .availabilityinfo" "css_element"
|
||||||
And I should see "It is before" in the "#section-2 .availabilityinfo" "css_element"
|
And I should see "It is before" in the "#section-2 .availabilityinfo" "css_element"
|
||||||
And I should see "hidden otherwise" in the "#section-2 .availabilityinfo" "css_element"
|
And I should see "hidden otherwise" in the "#section-2 .availabilityinfo" "css_element"
|
||||||
|
And I click on "Show more" "button" in the "Page 2" "activity"
|
||||||
And I should see "Email address" in the "#section-2 .availabilityinfo" "css_element"
|
And I should see "Email address" in the "#section-2 .availabilityinfo" "css_element"
|
||||||
|
And I click on "Show less" "button" in the "#section-2 .availabilityinfo" "css_element"
|
||||||
|
And I should not see "Email address" in the "#section-2 .availabilityinfo" "css_element"
|
||||||
|
|
||||||
# Page 3 should not have available info.
|
# Page 3 should not have available info.
|
||||||
And "#section-3 .availabilityinfo" "css_element" should not exist
|
And "#section-3 .availabilityinfo" "css_element" should not exist
|
||||||
@ -114,6 +118,11 @@ Feature: display_availability
|
|||||||
And I click on "Date" "button" in the "Add restriction..." "dialogue"
|
And I click on "Date" "button" in the "Add restriction..." "dialogue"
|
||||||
And I set the field "direction" to "until"
|
And I set the field "direction" to "until"
|
||||||
And I set the field "x[year]" to "2013"
|
And I set the field "x[year]" to "2013"
|
||||||
|
And I press "Add restriction..."
|
||||||
|
And I click on "User profile" "button" in the "Add restriction..." "dialogue"
|
||||||
|
And I set the field "User profile field" to "Email address"
|
||||||
|
And I set the field "Value to compare against" to "email@example.com"
|
||||||
|
And I set the field "Method of comparison" to "is equal to"
|
||||||
And I press "Save changes"
|
And I press "Save changes"
|
||||||
|
|
||||||
# Section 2 is the same but hidden from students
|
# Section 2 is the same but hidden from students
|
||||||
@ -130,7 +139,7 @@ Feature: display_availability
|
|||||||
And I am on "Course 1" course homepage
|
And I am on "Course 1" course homepage
|
||||||
|
|
||||||
# Check display
|
# Check display
|
||||||
Then I should see "Available until" in the "#section-1 .availabilityinfo" "css_element"
|
Then I should see "Not available unless" in the "#section-1 .availabilityinfo" "css_element"
|
||||||
And I should see "Available until" in the "#section-2 .availabilityinfo" "css_element"
|
And I should see "Available until" in the "#section-2 .availabilityinfo" "css_element"
|
||||||
And I should see "hidden otherwise" in the "#section-2 .availabilityinfo" "css_element"
|
And I should see "hidden otherwise" in the "#section-2 .availabilityinfo" "css_element"
|
||||||
|
|
||||||
@ -144,7 +153,11 @@ Feature: display_availability
|
|||||||
|
|
||||||
# Section 1 should be visible and show info.
|
# Section 1 should be visible and show info.
|
||||||
And I should see "Topic 1" in the "region-main" "region"
|
And I should see "Topic 1" in the "region-main" "region"
|
||||||
And I should see "Available until" in the "#section-1 .availabilityinfo" "css_element"
|
And I should see "Not available unless" in the "#section-1 .availabilityinfo" "css_element"
|
||||||
|
And I click on "Show more" "button" in the "#section-1 .availabilityinfo" "css_element"
|
||||||
|
And I should see "Email address" in the "#section-1 .availabilityinfo" "css_element"
|
||||||
|
And I click on "Show less" "button" in the "#section-1 .availabilityinfo" "css_element"
|
||||||
|
And I should not see "Email address" in the "#section-1 .availabilityinfo" "css_element"
|
||||||
|
|
||||||
# Section 2 should not be available at all
|
# Section 2 should not be available at all
|
||||||
And I should not see "Topic 2" in the "region-main" "region"
|
And I should not see "Topic 2" in the "region-main" "region"
|
||||||
|
@ -108,11 +108,7 @@ class availability extends section_avalability {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$info = [];
|
$info = [];
|
||||||
$formattedinfo = \core_availability\info::format_info(
|
$info[] = $this->get_availability_data($output, $this->mod->availableinfo, 'isrestricted');
|
||||||
$this->mod->availableinfo,
|
|
||||||
$this->mod->get_course()
|
|
||||||
);
|
|
||||||
$info[] = $this->availability_info($formattedinfo, 'isrestricted');
|
|
||||||
return $info;
|
return $info;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,11 +147,7 @@ class availability extends section_avalability {
|
|||||||
if (!$mod->visible) {
|
if (!$mod->visible) {
|
||||||
$hidinfoclass .= ' hide';
|
$hidinfoclass .= ' hide';
|
||||||
}
|
}
|
||||||
$formattedinfo = info::format_info(
|
$info[] = $this->get_availability_data($output, $fullinfo, $hidinfoclass);
|
||||||
$fullinfo,
|
|
||||||
$mod->get_course()
|
|
||||||
);
|
|
||||||
$info[] = $this->availability_info($formattedinfo, $hidinfoclass);
|
|
||||||
|
|
||||||
return $info;
|
return $info;
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
namespace core_courseformat\output\local\content\section;
|
namespace core_courseformat\output\local\content\section;
|
||||||
|
|
||||||
use context_course;
|
use context_course;
|
||||||
|
use core_availability_multiple_messages;
|
||||||
use core\output\named_templatable;
|
use core\output\named_templatable;
|
||||||
use core_availability\info;
|
use core_availability\info;
|
||||||
use core_availability\info_section;
|
use core_availability\info_section;
|
||||||
@ -57,6 +58,9 @@ class availability implements named_templatable, renderable {
|
|||||||
/** @var stdClass|null the instance export data */
|
/** @var stdClass|null the instance export data */
|
||||||
protected $data = null;
|
protected $data = null;
|
||||||
|
|
||||||
|
/** @var int Availability excerpt text max size treshold */
|
||||||
|
protected const AVAILABILITY_EXCERPT_MAXSIZE = 100;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
@ -124,7 +128,7 @@ class availability implements named_templatable, renderable {
|
|||||||
* are going to be unavailable etc). This logic is the same as for
|
* are going to be unavailable etc). This logic is the same as for
|
||||||
* activities.
|
* activities.
|
||||||
*
|
*
|
||||||
* @param renderer_base $output typically, the renderer that's calling this function
|
* @param \renderer_base $output typically, the renderer that's calling this function
|
||||||
* @return stdclass data context for a mustache template
|
* @return stdclass data context for a mustache template
|
||||||
*/
|
*/
|
||||||
protected function get_info(\renderer_base $output): array {
|
protected function get_info(\renderer_base $output): array {
|
||||||
@ -142,30 +146,115 @@ class availability implements named_templatable, renderable {
|
|||||||
if ($section->availableinfo) {
|
if ($section->availableinfo) {
|
||||||
// Note: We only get to this function if availableinfo is non-empty,
|
// Note: We only get to this function if availableinfo is non-empty,
|
||||||
// so there is definitely something to print.
|
// so there is definitely something to print.
|
||||||
$formattedinfo = info::format_info($section->availableinfo, $section->course);
|
$info[] = $this->get_availability_data($output, $section->availableinfo, 'isrestricted');
|
||||||
$info[] = $this->availability_info($formattedinfo, 'isrestricted');
|
|
||||||
}
|
}
|
||||||
} else if ($canviewhidden && !empty($CFG->enableavailability)) {
|
} else if ($canviewhidden && !empty($CFG->enableavailability)) {
|
||||||
// Check if there is an availability restriction.
|
// Check if there is an availability restriction.
|
||||||
$ci = new info_section($section);
|
$ci = new info_section($section);
|
||||||
$fullinfo = $ci->get_full_information();
|
$fullinfo = $ci->get_full_information();
|
||||||
if ($fullinfo) {
|
if ($fullinfo) {
|
||||||
$formattedinfo = info::format_info($fullinfo, $section->course);
|
$info[] = $this->get_availability_data($output, $fullinfo, 'isrestricted isfullinfo');
|
||||||
$info[] = $this->availability_info($formattedinfo, 'isrestricted isfullinfo');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $info;
|
return $info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the basic availability information data.
|
||||||
|
*
|
||||||
|
* @param \renderer_base $output typically, the renderer that's calling this function
|
||||||
|
* @param string|core_availability_multiple_messages $availabilityinfo the avalability info
|
||||||
|
* @param string $additionalclasses additional css classes
|
||||||
|
* @return stdClass the availability information data
|
||||||
|
*/
|
||||||
|
protected function get_availability_data($output, $availabilityinfo, $additionalclasses = ''): stdClass {
|
||||||
|
// At this point, availabilityinfo is either a string or a renderable. We need to handle both cases in a different way.
|
||||||
|
if (is_string($availabilityinfo)) {
|
||||||
|
$data = $this->availability_info_from_string($output, $availabilityinfo);
|
||||||
|
} else {
|
||||||
|
$data = $this->availability_info_from_output($output, $availabilityinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data->classes = $additionalclasses;
|
||||||
|
|
||||||
|
$additionalclasses = array_filter(explode(' ', $additionalclasses));
|
||||||
|
if (in_array('ishidden', $additionalclasses)) {
|
||||||
|
$data->ishidden = 1;
|
||||||
|
} else if (in_array('isstealth', $additionalclasses)) {
|
||||||
|
$data->isstealth = 1;
|
||||||
|
} else if (in_array('isrestricted', $additionalclasses)) {
|
||||||
|
$data->isrestricted = 1;
|
||||||
|
if (in_array('isfullinfo', $additionalclasses)) {
|
||||||
|
$data->isfullinfo = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the basic availability information data from a string.
|
||||||
|
* Just shorten availability text to generate the excerpt text.
|
||||||
|
*
|
||||||
|
* @param \renderer_base $output typically, the renderer that's calling this function
|
||||||
|
* @param string $availabilityinfo the avalability info
|
||||||
|
* @return stdClass the availability information data
|
||||||
|
*/
|
||||||
|
protected function availability_info_from_string(\renderer_base $output, string $availabilityinfo): stdClass {
|
||||||
|
$course = $this->format->get_course();
|
||||||
|
|
||||||
|
$text = info::format_info($availabilityinfo, $course);
|
||||||
|
$data = ['text' => $text];
|
||||||
|
|
||||||
|
if (strlen(html_to_text($text)) > self::AVAILABILITY_EXCERPT_MAXSIZE) {
|
||||||
|
$data['excerpt'] = shorten_text($text, self::AVAILABILITY_EXCERPT_MAXSIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (object) $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the basic availability information data from a renderable.
|
||||||
|
* Use the header and the first item to generate the excerpt text.
|
||||||
|
*
|
||||||
|
* @param \renderer_base $output typically, the renderer that's calling this function
|
||||||
|
* @param core_availability_multiple_messages $availabilityinfo the avalability info
|
||||||
|
* @return stdClass the availability information data
|
||||||
|
*/
|
||||||
|
protected function availability_info_from_output(
|
||||||
|
\renderer_base $output,
|
||||||
|
core_availability_multiple_messages $availabilityinfo
|
||||||
|
): stdClass {
|
||||||
|
$course = $this->format->get_course();
|
||||||
|
|
||||||
|
$renderable = new \core_availability\output\availability_info($availabilityinfo);
|
||||||
|
// We need to export_for_template() instead of directly render, to reuse the info for both 'text' and 'excerpt'.
|
||||||
|
$info = $renderable->export_for_template($output);
|
||||||
|
|
||||||
|
$text = $output->render_from_template('core_availability/availability_info', $info);
|
||||||
|
$data = ['text' => info::format_info($text, $course)];
|
||||||
|
|
||||||
|
if (!empty($info->items)) {
|
||||||
|
$excerpttext = $info->header . ' ' . $info->items[0]->header;
|
||||||
|
$data['excerpt'] = info::format_info($excerpttext, $course);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (object) $data;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the basic availability information data.
|
* Generate the basic availability information data.
|
||||||
*
|
*
|
||||||
|
* @deprecated since Moodle 4.3 MDL-78204. Please use {@see self::get_availability_data} instead.
|
||||||
|
* @todo MDL-78489 This will be deleted in Moodle 4.7.
|
||||||
* @param string $text the formatted avalability text
|
* @param string $text the formatted avalability text
|
||||||
* @param string $additionalclasses additional css classes
|
* @param string $additionalclasses additional css classes
|
||||||
* @return stdClass the availability information data
|
* @return stdClass the availability information data
|
||||||
*/
|
*/
|
||||||
protected function availability_info($text, $additionalclasses = ''): stdClass {
|
protected function availability_info($text, $additionalclasses = ''): stdClass {
|
||||||
|
debugging('Use of ' . __FUNCTION__ . '() have been deprecated, ' .
|
||||||
|
'please use core_courseformat\output\local\content\section\availability::get_availability_data()', DEBUG_DEVELOPER);
|
||||||
|
|
||||||
$data = (object)[
|
$data = (object)[
|
||||||
'text' => $text,
|
'text' => $text,
|
||||||
|
43
course/format/templates/local/content/availability.mustache
Normal file
43
course/format/templates/local/content/availability.mustache
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
{{!
|
||||||
|
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/availability
|
||||||
|
|
||||||
|
Displays the availability contents with excerpt version if needed.
|
||||||
|
|
||||||
|
Example context (json):
|
||||||
|
{
|
||||||
|
"text": "Not available unless: <ul><li>It is on or after <strong>8 June 2012</strong></li><li>You achieve higher than a certain score in <strong>Course total</strong></li></ul>",
|
||||||
|
"excerpt": "Not available unless: It is on or after <strong>8 June 2012</strong>"
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
{{^excerpt}}
|
||||||
|
{{#pix}}t/unlock, core{{/pix}} {{{text}}}
|
||||||
|
{{/excerpt}}
|
||||||
|
{{#excerpt}}
|
||||||
|
{{< core/showmore }}
|
||||||
|
{{$collapsedcontent}}
|
||||||
|
{{#pix}}t/unlock, core{{/pix}} <span class="availability-excerpt"> {{{excerpt}}} ... </span>
|
||||||
|
{{/collapsedcontent}}
|
||||||
|
{{$expandedcontent}}
|
||||||
|
{{#pix}}t/unlock, core{{/pix}} {{{text}}}
|
||||||
|
{{/expandedcontent}}
|
||||||
|
{{$buttonextraclasses}}font-weight-bold{{/buttonextraclasses}}
|
||||||
|
{{$collapsedextraclasses}}text-truncate pr-2{{/collapsedextraclasses}}
|
||||||
|
{{$expandedextraclasses}}py-2{{/expandedextraclasses}}
|
||||||
|
{{/core/showmore }}
|
||||||
|
{{/excerpt}}
|
@ -41,7 +41,7 @@
|
|||||||
<span class="badge badge-pill badge-warning">{{{text}}}</span>
|
<span class="badge badge-pill badge-warning">{{{text}}}</span>
|
||||||
{{/isrestricted}}
|
{{/isrestricted}}
|
||||||
{{#isrestricted}}
|
{{#isrestricted}}
|
||||||
<div> {{#pix}}t/unlock, core{{/pix}} {{{text}}} </div>
|
{{> core_courseformat/local/content/availability }}
|
||||||
{{/isrestricted}}
|
{{/isrestricted}}
|
||||||
</div>
|
</div>
|
||||||
{{/info}}
|
{{/info}}
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
<span class="badge badge-pill badge-warning">{{{text}}}</span>
|
<span class="badge badge-pill badge-warning">{{{text}}}</span>
|
||||||
{{/isrestricted}}
|
{{/isrestricted}}
|
||||||
{{#isrestricted}}
|
{{#isrestricted}}
|
||||||
<div> {{#pix}}t/unlock, core{{/pix}} {{{text}}} </div>
|
{{> core_courseformat/local/content/availability }}
|
||||||
{{/isrestricted}}
|
{{/isrestricted}}
|
||||||
</div>
|
</div>
|
||||||
{{/info}}
|
{{/info}}
|
||||||
|
@ -12,6 +12,8 @@ Some considerations about the activitybadge feature:
|
|||||||
- An optional URL to redirect the user when the badge is clicked.
|
- 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.
|
- 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).
|
- Optionally, any other extra HTML attributes to the badge element (for example, data attributes).
|
||||||
|
* Protected function `core_courseformat\output\local\content\section\availability::availability_info()` has been deprecated,
|
||||||
|
`core_courseformat\output\local\content\section\availability::get_availability_data()` should be used instead.
|
||||||
|
|
||||||
=== 4.2 ===
|
=== 4.2 ===
|
||||||
* New core_courseformat\base::get_context() to get the course context directly from the format instance.
|
* New core_courseformat\base::get_context() to get the course context directly from the format instance.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user