6、设置版块的标题 我想在 configuration page 里设置 block 的 title ,则在 config_instance.html 里添加 < input type= “text” name= “title” value= “<?php echo $this->config->title; ?>”/> 但由于 $this->config 变量不能在 init()里使用以及 $this->title 不能在 get_content()里改变,所以无法在 init() 里或在 get_content()里使用下列代码 $this -> title = $this->config->title; 怎么办?就要使用到 specialization() 来给 title 赋值 ,该方法是紧接着 init() 后被调用,即是在版块内容生成之前被调用。 因此,提供一个specialization()方法是为任何需要“尽快”采取行动,这种情况下的配置数据的自然选择。即可以对 this->config 包含的值进行预处理。例如下列代码会在 specialization()方法里 检查如果 $this->config->title 为 empty ,则给一个默认值(’Hello world!’)给它。 function specialization(){ if( ! empty ( $this -> config -> title )){ $this -> title=$this -> config -> title ; }else{ $this -> config -> title=’Hello world!’ ; } if( empty ( $this -> config -> text )){ $this -> config -> text=’Some text …’ ; } } 7、block自动隐藏 有时你可能想开发一个这样的block :当有数据时,就显示该block,但当没有数据时,就隐藏整个block。典型的例子是”recent activity”block ,如果没有recent activity ,该 block就会自动隐藏。 怎么实现这个功能? 很简单,只需要在 get_content() 里设置 $this->content->text and $this->content->footer 为空字节即可。(moodle在处理block 时,会先调用is_empty()方法来检查它,如果text和footer都是empty,就不会显示这个block 。 注意:不管该block的title是不是empty,也不管hide_header()方法是hide or show header ,都不会影响上述show/hide block 的行为。即当 content is empty 时,即使title不为empty,也不hide header ,moodle 照样还是会隐藏该 block 。 8、实现在同一课程里添加多个同一block实例 如果你希望在同一个课程里添加同一个block的多个实例,则要在block 类里添加 instance_allow_multiple()方法: function instance_allow_multiple() { return true; } 要注意的是 即使block本身已经添加以上方法, admin 还是可以通过 Administration/Configuration/Blocks page 来禁用多个功能。 如果“ allow multiple ”和“ allow config ”同时存在,则会自动禁用允许配置功能。 9、实现全局统一修改效果 有时候 admin 可能希望他能够有一个地方对某个block的所有实例能一次性进行设置。 例如, admin希望 helloworld block 的content 长度不要超过200字,或者 content只允许纯文本(plain text) ,如果是html text ,则过滤HTML标签。 首先,在 block 类里添加下列代码 function has_config (){ return true ; } 然后,我们需要创建一个HTML文件config_global.html,用于打印输出配置屏幕。在该文件里,我们添加一个checkbox saying “Do not allow HTML in the content” 以及一个 “submit” button。然后并复制粘贴到以下: <div style=”text-align: center;”> <input type=”hidden” name=”block_helloworld_strict” value=”0″ /> <input type=”checkbox” name=”block_helloworld_strict” value=”1″ <?php if(!empty($CFG->block_helloworld_strict)) echo ‘checked=”checked”‘; ?> /> <?php print_string(‘donotallowhtml’, ‘block_helloworld’); ?> <p> <input type=”submit” value=”<?php print_string(‘savechanges’); ?>” /> </p> </div> 上面的代码会 global configure 变量 block_helloworld_strict ,该变量的值在submit时会储存在 $CFG-> block_helloworld_strict 里 。注意设置的变量名一定要是唯一,如果别的module 在 $CFG 使用同样的变量名,那就惨啦。所以把变量命名为 block_helloworld_strict应该是 ok 的。 上面代码你会奇怪为什么有2个 input field (一个 hidden [always 0], 一个 checkbox )的 name 都为 “ block_helloworld_strict ” ?这是一种技巧。因为如果没有 hidden input field ,当 checkbox 没有被勾上,该 variable (block_helloworld_strict=0) 根本就不会传给给request 。这样就无法设置 $CFG->block_helloworld_strict=0 。因此加多一个 hidden 是为了保证 request param 里一定有 block_helloworld_strict变量 。 原理就是:当 PHP 处理 form request 时,会按这些变量在 form 里的出现顺序进行处理。当遇到一个之前已经存在并处理了的变量 ,新值就会覆盖旧值。利用这一点,我们就把 hidden “block_helloworld_strict =0” 放在前面, checkbox 放在后面。如果没勾上 checkbox ,就会有 hidden 的值 0 ,如果勾上,就会使用 checkbox 的值1 。 如果你觉得用 2 个 input field 来使用同一个 name 太令代码复杂,有一个替代方案: overwrite config_save() method (当在 global configuration page click submit button 时,就会调用它) 。 下面代码是缺省的 config_save() method ,其中参数 $data 是 form request variable key value pair array 。 function config_save($data){ // Default behaviour: save all variables as $CFG properties // You don’t need to override this if you ‘re satisfied with the above foreach ($data as $name => $value) { set_config($name, $value) ; } returnTRUE ; } 我们重写它使得它会 check 是否存在 block_helloworld_strict 变量。如果不存在,就表示没有勾上checkbox 。使用这个方法就不需要添加 hidden input field 了。 function config_save( $data ){ if ( isset($data[‘block_helloworld_strict’]) ){ set_config(‘block_helloworld_strict’, ‘1’); } else{ set_config(‘block_helloworld_strict’, ‘0’); } return true ; } OK 。在 global confirmation page 里设置了 $CFG->block_helloworld_strict ,那在我们的 helloworld block 里如何使用它? 其实 $CFG 是一个超全局变量,任何地方都可以使用它 。 那么在本例中我们希望根据 $CFG->block_helloworld_strict 这个 block global configuration ,来使得 block instance 的 content 只能是 plain text ,如果有 html text 就 filter 。这时我们要overwrite instance_config_save() method ! instance_config_save() 该方法允许你 覆盖实例配置数据的存储机制,即当在某一个 block instance 的 configuration page 里 click submit button 时,就会先调用该方法,你可以重写它来对 submit form data 进行处理,处理完的最后再调用parent::instance_config_save($data) 来调用父类缺省的 instance_config_save() method。该方法的参数是一个 associative array ,它包含有 submit form 的 key/value pair 。 缺省的 instance_config_save() 如下: function instance_config_save($data) { $data = stripslashes_recursive($data); $this->config = $data; return set_field(‘block_instance’, ‘configdata’, base64_encode(serialize($data)), ‘id’, $this->instance->id);} 从上面缺省的方法可以看到,它会先调用 stripslashes_recursive 方法对 submitted POST data 进行 stripslashes and recursive 的处理,然后才调用 set_field 方法把处理后的 data 存到 db 里该 block instance record 的 “configdata” field 里 。 好了,现在我们通过重写 instance_config_save 来过滤HTML标签 function instance_config_save( $data ){ global$CFG ; if ( ! empty ( $CFG -> block_helloworld_strict)){ //filter html tag $data->text = strip_tags($data->text); } // call parent instance_config_save method return parent::instance_config_save($data); } 10、隐藏表头:hide_header() |
Moodle开发笔记8-Block开发(三)
6、设置版块的标题 我想在 configuration page 里设置 block 的 title ,则在 config_instance.html …