Moodle开发笔记8-Block开发(三)

6、设置版块的标题     我想在 configuration page 里设置 block 的 title ,则在 config_instance.html …

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()
    如果你想 hide block title/header ,那么添加下列方法到 block 类里
function hide_header(){
   return true ;
}
   注意: moodle 不允许在 block 的 init() method 里把 title 设置为 empty 。
未完,待续……

作者: admin

为您推荐

联系我们

联系我们

邮箱:

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部