Blocks 2.0

Blocks 2.0

by Howard Miller -
Number of replies: 13
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
Before I get confused and/or start asking more ridiculous questions, is this what was actually implemented?

http://docs.moodle.org/en/Development:Very_flexible_block_system_proposal
Average of ratings: -
In reply to Howard Miller

Re: Blocks 2.0

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Yes, but...

That document was written before I wrote the code Naturally some details changed during implementation.

However, I think that document still gives a pretty accurate overview of the bit picture. When it comes to the details, you would be better of reading the PHPdoc comments in the code.

In reply to Tim Hunt

Re: Blocks 2.0

by Howard Miller -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
Yes - I see a few things are different but I got the general idea.

One further question... and again I'm not sure I'm putting this properly... how do you programmatically 'require' certain blocks to be on a page? I might mean how do you set the default blocks on a page or I might even mean how do new blocks tell Moodle which page they should be on wink But, if I create a new Moodle page can I specify the blocks that are on it somehow?
In reply to Howard Miller

Re: Blocks 2.0

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

There you enter deep waters, and I'm afraid it depends on exactly what you want to achive, although there are lots of options.

I think that fundamentally, blocks are something that users control. That is, they can always click "turn editing on", and rearrange them if they want - if they have sufficient permissions over that page.

However, there are various ways that developers can make things easy for users, or admins can make things easy for all users.

1. Site-wide sticky blocks If you take Moodle's settings and navigation blocks. Those have to appear on every page, or Moodle is basically unsuable. So, by default, when you install Moodle, it adds those two as site-wide sticky blocks. That is

context: {system context} + sub-contexts
page type: *
sub-page: *

However, if desired, an admin could remove that block_navigation instance, and replace it with, for, example a block_ounavigation - if their Moodle site has particular requirements.

For your situation, the equivalent would be a sticky block

context: {system context} + sub-contexts
page type: local-howard-blockspage
sub-page: *

or whatever the appropriate page type is. (Note the option Admin -> Development -> Debugging -> Show page information.)

2. Default blocks on a particular type of page. For example, whenever you create a course, certain blocks are added to that course page by default. I can't remember how that works, nor how easy it is for admins to configure that. But once the course is created, teachers can move the blocks around as they wish.

3. Fake blocks I said above, block are fundamentally owned by the user, so developers should only be able to set up defaults. However, sometimes you want things that look like blocks, but which are fundamentally part of the page they are on. For example, the new navigation that appears during a quiz attempt in Moodle 2.0, or the lesson has some things like this.

To get something like that to appear on the page, use

$PAGE->blocks->add_pretend_block(...);

(e.g. https://github.com/moodle/moodle/blob/cvshead/mod/quiz/attempt.php#L97). The block_contents object that you need to pass as the first argument is something that is used when outputting blocks. It holds all the bits of HTML that you need to output the block, like the title, contents, and so on.

Grrr! I have just noticed that we have an inconsistend API. To go with the $PAGE->blocks->add_pretend_block method, there is another method $PAGE->blocks->show_only_fake_blocks(). I am pretty sure I know who screwed up there (me). I suppose it is too late to fix it sad.

In reply to Tim Hunt

Re: Blocks 2.0

by Howard Miller -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
Thanks Tim,

I am creating a page very similar to the my moodle page. The difference is that the admin adds the blocks and the users can't change them. The page has system context and this seems to more or less work (non-admin users don't get the edit button).

So, the other bit would be quite similar to the Course pages where the Teacher can control the blocks but the students can't (unless that's changed).

It would be nice to be able to create a suitable default. In 1.9 you could override the default Course blocks with a "hidden" config setting. I'll see if I can find that and look at what it does.
In reply to Howard Miller

Re: Blocks 2.0

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Yes, please find out how the course default stuff works. I expect it is still a bit of a hack (hidden config settings, like in 1.9).

It would be nice to get a proper mechanism in place for default blocks on certain sorts of page. Except that I don't think a completely general mechanism is possible. The main problem is that there is no general way to know when a new page of a particular type is created. For example, the course page is created when a user adds a new course. A mymoodle page is created when a new user is created, either by an admin, or an enrolment plugin, except that in the mymoodle case, it may make more sense to create the blocks the first time the user goes to their own my moodle page. And so on.

However, we should certainly have code for:

1. an admin setting class for "default blocks on page type X".

2. a function which, given the value of that admin setting, and a page, adds all those default blocks to that page.

That would make it very easy for developers to make it easy for admins to configure default blocks on any page type they care about.

In reply to Tim Hunt

Re: Blocks 2.0

by Howard Miller -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
Well,

Yes the hidden config settings are still there. Then there's a lot of fiddling around to work out what the list of blocks should be in a new course, but it winds up as....



$page = new moodle_page();
$page->set_course($course);
$page->blocks->add_blocks($blocknames, $pagetypepattern);


I'm not sure if there's an equivalent to 'set_course' for non-course pages. I suppose just setting the contexts and such will do the job. As this is a one-off plugin, the db/install.php script should be sufficient for my needs to set this up. This obviously doesn't work where there are multiple instances but most plugins seem to have a function that runs after an instance is created.
In reply to Howard Miller

Re: Blocks 2.0

by Howard Miller -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
Just for the record.... and I'm not sure if this is 'optimal' code. In local/mynewpage/db/install.php:



function xmldb_local_mynewpage_install() {

// add some default blocks to mynewpage
// (yes, I know this isn't really what this is for!!)
$systemcontext = get_context_instance(CONTEXT_SYSTEM);
$page = new moodle_page();
$page->set_context( $systemcontext );
$page->set_pagetype( 'local-mynewpage-index' );
$page->set_pagelayout( 'mydashboard' );
$page->blocks->add_region('content');
$defaultblocks = array(
'side_pre' => array('course_list'),
'content' => array('online_users','calendar_month'),
'side_post' => array('news_items')
);
$page->blocks->add_blocks($defaultblocks);
}


The page in question is displayed at local/mynewpage/index.php
In reply to Tim Hunt

Re: Blocks 2.0

by Myles Carrick -
hi Tim,

That would indeed be nice.

What I'm looking to do is perhaps a little different to this - and I initially thought it was how you'd implemented the new structure. I'd love to be able to specify a block instance that could appear on all pages of a particular type - e.g. on all Assignment pages, or all Forum pages - something like a page-type sticky block.

Is that going to be possible, or are there insurmountable challenges in the way that the contexts are determined?

Cheers mate - loving the much more flexible architecture!
Average of ratings: Useful (1)
In reply to Myles Carrick

Re: Blocks 2.0

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

I think that is possible, because page-type there allows wildcards. So you can set up a block to appear on pages that match.

context: {system context} + sub-contexts
page type: mod-forum-*
sub-page: *

To really understand what is possible, you need to meditate on this database query: https://github.com/moodle/moodle/blob/master/lib/blocklib.php#L540 until you have achieved enlightenment.

In reply to Tim Hunt

Re: Blocks 2.0

by Myles Carrick -
hi Tim,

Thanks for the reply. The limitation seem indeed to be with the contexts.

When I'm on an activity page (say, a Forum), the available settings look like:

Page contexts:
Display on 'Forum: Moodle News' only
Display on 'Forum: Moodle News' and any pages within it

Restrict to these page types:
mod-forum-view
mod-*-view (Any main activity module page)
mod-forum-view-*
mod-forum-*
mod-* (Any activity module page)
* (Any page)


The issue seems to be that it'll only let me specify child contexts of that activity (i.e. nothing/nowhere else if it's an activity with no subpages), whereas we want it to think its highest possible scope for the context tree is much higher (categories and courses). Is that by design?

Cheers,

Myles
In reply to Myles Carrick

Re: Blocks 2.0

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Yes. The UI is tricky (because at the place wherey we have to display the form, we only have certain information readily available, so we can only display certain options). So, you have to do something like this:

  1. Add the block to the site front page.
  2. Edit the block to say it is accessible throughout the whole site, on page-type *.
  3. Then go to any forum. You can see the block and change the settings to 'display throughout  the entire site, page type mod-forum-*, or whatever.

I suspect we will want to improve this aspect of the blocks UI at some point wink

Average of ratings: Useful (1)
In reply to Tim Hunt

Re: Blocks 2.0

by Myles Carrick -
Thanks, Tim - that's truly sensational.
You're right - it'll be great to figure out how to get the UI to handle all of this.
In reply to Myles Carrick

Re: Blocks 2.0

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

I'm not sure that sensational is the word I would use for it. wink

Anyway, glad you got it working.