Commit b11916d3 authored by Marina Glancy's avatar Marina Glancy
Browse files

MDL-56586 blocks: allow theme to manage "Add a block" select

parent 692c1bf3
......@@ -83,16 +83,19 @@ Scenario: Block should select current activity by default
When I add the "Activity results" block
And I configure the "Activity results" block
Then the field "id_config_activitygradeitemid" matches value "Test assignment 1"
And I press "Cancel"
And I follow "Course 1"
And I follow "Test assignment 2"
And I add the "Activity results" block
And I configure the "Activity results" block
And the field "id_config_activitygradeitemid" matches value "Test assignment 2"
And I press "Cancel"
And I follow "Course 1"
And I follow "Test assignment 3"
And I add the "Activity results" block
And I configure the "Activity results" block
And the field "id_config_activitygradeitemid" matches value "Test assignment 3"
And I press "Cancel"
And I follow "Course 1"
And I follow "Test page name"
And I add the "Activity results" block
......
......@@ -42,6 +42,14 @@ define('BUI_CONTEXTS_ENTIRE_SITE', 2);
define('BUI_CONTEXTS_CURRENT', 0);
define('BUI_CONTEXTS_CURRENT_SUBS', 1);
// Position of "Add block" control, to be used in theme config as a value for $THEME->addblockposition:
// - default: as a fake block that is displayed in editing mode
// - flatnav: "Add block" item in the flat navigation drawer in editing mode
// - custom: none of the above, theme will take care of displaying the control.
define('BLOCK_ADDBLOCK_POSITION_DEFAULT', 0);
define('BLOCK_ADDBLOCK_POSITION_FLATNAV', 1);
define('BLOCK_ADDBLOCK_POSITION_CUSTOM', -1);
/**
* Exception thrown when someone tried to do something with a block that does
* not exist on a page.
......@@ -216,10 +224,12 @@ class block_manager {
($bi->instance_allow_multiple() || !$this->is_block_present($block->name)) &&
blocks_name_allowed_in_format($block->name, $pageformat) &&
$bi->user_can_addto($this->page)) {
$block->title = $bi->get_title();
$this->addableblocks[$block->name] = $block;
}
}
core_collator::asort_objects_by_property($this->addableblocks, 'title');
return $this->addableblocks;
}
......@@ -1141,7 +1151,8 @@ class block_manager {
$contents = $this->extracontent[$region];
}
$contents = array_merge($contents, $this->create_block_contents($this->blockinstances[$region], $output, $region));
if ($region == $this->defaultregion) {
if (($region == $this->defaultregion) && (!isset($this->page->theme->addblockposition) ||
$this->page->theme->addblockposition == BLOCK_ADDBLOCK_POSITION_DEFAULT)) {
$addblockui = block_add_block_ui($this->page, $output);
if ($addblockui) {
$contents[] = $addblockui;
......@@ -1286,8 +1297,10 @@ class block_manager {
* @return boolean true if anything was done. False if not.
*/
public function process_url_add() {
global $CFG, $PAGE, $OUTPUT;
$blocktype = optional_param('bui_addblock', null, PARAM_PLUGIN);
if (!$blocktype) {
if ($blocktype === null) {
return false;
}
......@@ -1297,7 +1310,54 @@ class block_manager {
throw new moodle_exception('nopermissions', '', $this->page->url->out(), get_string('addblock'));
}
if (!array_key_exists($blocktype, $this->get_addable_blocks())) {
$addableblocks = $this->get_addable_blocks();
if ($blocktype === '') {
// Display add block selection.
$addpage = new moodle_page();
$addpage->set_pagelayout('admin');
$addpage->blocks->show_only_fake_blocks(true);
$addpage->set_course($this->page->course);
$addpage->set_context($this->page->context);
if ($this->page->cm) {
$addpage->set_cm($this->page->cm);
}
$addpagebase = str_replace($CFG->wwwroot . '/', '/', $this->page->url->out_omit_querystring());
$addpageparams = $this->page->url->params();
$addpage->set_url($addpagebase, $addpageparams);
$addpage->set_block_actions_done();
// At this point we are going to display the block selector, overwrite global $PAGE ready for this.
$PAGE = $addpage;
// Some functions use $OUTPUT so we need to replace that too.
$OUTPUT = $addpage->get_renderer('core');
$site = get_site();
$straddblock = get_string('addblock');
$PAGE->navbar->add($straddblock);
$PAGE->set_title($straddblock);
$PAGE->set_heading($site->fullname);
echo $OUTPUT->header();
echo $OUTPUT->heading($straddblock);
if (!$addableblocks) {
echo $OUTPUT->box(get_string('noblockstoaddhere'));
echo $OUTPUT->container($OUTPUT->action_link($addpage->url, get_string('back')), 'm-x-3 m-b-1');
} else {
foreach ($addableblocks as $blockname => $block) {
$url = new moodle_url($addpage->url, array('sesskey' => sesskey(), 'bui_addblock' => $blockname));
echo $OUTPUT->container($OUTPUT->single_button($url, $block->title), 'm-x-3 m-b-1');
}
echo $OUTPUT->container($OUTPUT->action_link($addpage->url, get_string('cancel')), 'm-x-3 m-b-1');
}
echo $OUTPUT->footer();
// Make sure that nothing else happens after we have displayed this form.
exit;
}
if (!array_key_exists($blocktype, $addableblocks)) {
throw new moodle_exception('cannotaddthisblocktype', '', $this->page->url->out(), $blocktype);
}
......@@ -1332,6 +1392,7 @@ class block_manager {
if (!$confirmdelete) {
$deletepage = new moodle_page();
$deletepage->set_pagelayout('admin');
$deletepage->blocks->show_only_fake_blocks(true);
$deletepage->set_course($this->page->course);
$deletepage->set_context($this->page->context);
if ($this->page->cm) {
......@@ -1452,6 +1513,7 @@ class block_manager {
$editpage = new moodle_page();
$editpage->set_pagelayout('admin');
$editpage->blocks->show_only_fake_blocks(true);
$editpage->set_course($this->page->course);
//$editpage->set_context($block->context);
$editpage->set_context($this->page->context);
......@@ -2072,12 +2134,8 @@ function block_add_block_ui($page, $output) {
$menu = array();
foreach ($missingblocks as $block) {
$blockobject = block_instance($block->name);
if ($blockobject !== false && $blockobject->user_can_addto($page)) {
$menu[$block->name] = $blockobject->get_title();
}
$menu[$block->name] = $block->title;
}
core_collator::asort($menu);
$actionurl = new moodle_url($page->url, array('sesskey'=>sesskey()));
$select = new single_select($actionurl, 'bui_addblock', $menu, null, array(''=>get_string('adddots')), 'add_block');
......
......@@ -3764,6 +3764,19 @@ class flat_navigation extends navigation_node_collection {
$flat->key = 'sitesettings';
$this->add($flat);
}
// Add-a-block in editing mode.
if (isset($this->page->theme->addblockposition) &&
$this->page->theme->addblockposition == BLOCK_ADDBLOCK_POSITION_FLATNAV &&
$PAGE->user_is_editing() && $PAGE->user_can_edit_blocks() &&
$PAGE->blocks->get_addable_blocks()) {
$url = new moodle_url($PAGE->url, ['bui_addblock' => '', 'sesskey' => sesskey()]);
$addablock = navigation_node::create(get_string('addblock'), $url);
$flat = new flat_navigation_node($addablock, 0);
$flat->set_showdivider(true);
$flat->key = 'addblock';
$this->add($flat);
}
}
}
......
......@@ -546,7 +546,7 @@ class theme_config {
'rendererfactory', 'csspostprocess', 'editor_sheets', 'rarrow', 'larrow', 'uarrow', 'darrow',
'hidefromselector', 'doctype', 'yuicssmodules', 'blockrtlmanipulations',
'lessfile', 'extralesscallback', 'lessvariablescallback', 'blockrendermethod',
'scss', 'extrascsscallback', 'prescsscallback', 'csstreepostprocessor');
'scss', 'extrascsscallback', 'prescsscallback', 'csstreepostprocessor', 'addblockposition');
foreach ($config as $key=>$value) {
if (in_array($key, $configurable)) {
......
......@@ -152,3 +152,4 @@ $THEME->prescsscallback = 'theme_boost_get_pre_scss';
$THEME->yuicssmodules = array();
$THEME->rendererfactory = 'theme_overridden_renderer_factory';
$THEME->undeletableblocktypes = '';
$THEME->addblockposition = BLOCK_ADDBLOCK_POSITION_FLATNAV;
......@@ -38,15 +38,8 @@ require_once(__DIR__ . '/../../../../blocks/tests/behat/behat_blocks.php');
class behat_theme_boost_behat_blocks extends behat_blocks {
public function i_add_the_block($blockname) {
$this->execute('behat_forms::i_set_the_field_to',
array("bui_addblock", $this->escape($blockname))
);
// If we are running without javascript we need to submit the form.
if (!$this->running_javascript()) {
$this->execute('behat_general::i_click_on_in_the',
array("Go", "button", "Add a block", "block"));
}
$this->execute('behat_navigation::i_select_from_flat_navigation_drawer', get_string('addblock'));
$this->execute('behat_forms::press_button', $blockname);
}
public function i_open_the_blocks_action_menu($blockname) {
......
......@@ -76,4 +76,56 @@ class behat_theme_boost_behat_navigation extends behat_navigation {
return $node;
}
/**
* Opens the flat navigation drawer if it is not already open
*
* @When /^I open flat navigation drawer$/
* @throws ElementNotFoundException Thrown by behat_base::find
*/
public function i_open_flat_navigation_drawer() {
if (!$this->running_javascript()) {
// Navigation drawer is always open without JS.
return;
}
$xpath = "//button[contains(@data-action,'toggle-drawer')]";
$node = $this->find('xpath', $xpath);
$expanded = $node->getAttribute('aria-expanded');
if ($expanded === 'false') {
$node->click();
$this->wait_for_pending_js();
}
}
/**
* Closes the flat navigation drawer if it is open (does nothing if JS disabled)
*
* @When /^I close flat navigation drawer$/
* @throws ElementNotFoundException Thrown by behat_base::find
*/
public function i_close_flat_navigation_drawer() {
if (!$this->running_javascript()) {
// Navigation drawer can not be closed without JS.
return;
}
$xpath = "//button[contains(@data-action,'toggle-drawer')]";
$node = $this->find('xpath', $xpath);
$expanded = $node->getAttribute('aria-expanded');
if ($expanded === 'true') {
$node->click();
$this->wait_for_pending_js();
}
}
/**
* Clicks link with specified id|title|alt|text in the flat navigation drawer.
*
* @When /^I select "(?P<link_string>(?:[^"]|\\")*)" from flat navigation drawer$/
* @throws ElementNotFoundException Thrown by behat_base::find
* @param string $link
*/
public function i_select_from_flat_navigation_drawer($link) {
$this->i_open_flat_navigation_drawer();
$this->execute('behat_general::i_click_on_in_the', [$link, 'link', '#nav-drawer', 'css_element']);
}
}
......@@ -57,6 +57,8 @@ information provided here is intended especially for theme designer.
* CLI svgtool.php has moved from theme/base/cli to admin/cli and paths should be relative to the new location.
* mod_chat will now display the 'course theme' option for all themes (previously it was only displayed on
bootstrap2 based themes).
* Theme can choose how to display "Add a block" control in $THEME->addblockposition, default value is
BLOCK_ADDBLOCK_POSITION_DEFAULT that displays it as a fake block in editing mode.
=== 3.1 ===
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment