You are here

4 通过hook_contextual_links_view_alter修改上下文链接

admin 的头像
Submitted by admin on 星期四, 2015-09-17 09:49

作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com

我们前面讲过contextual_pre_render_links里面,提供了hook_contextual_links_view_alter这个钩子函数。在上下文,链接呈现前,通过这个钩子函数,可以修改上下文链接,也就是说,可以伪造模拟出来一个链接。可能很多人不明白,为什么。在前面,我们看到这样的代码:

$types['contextual_links'] = array(

    '#pre_render' => array('contextual_pre_render_links'),

….

这里为contextual_links元素,指定了一个预呈现回调函数contextual_pre_render_links,就是说,在呈现上下文链接的时候,会调用这个函数,而在contextual_pre_render_links里面,通过“drupal_alter('contextual_links_view', $element, $items);”,就为我们提供了一个钩子函数,来修改上下文链接。

好了,我们来看一下,具体的实现代码:

/**

 * Implements hook_contextual_links_view_alter().

 */

function  breadcrumb2_contextual_links_view_alter(&$element, &$items) {

  if (isset($element['#contextual_links']['breadcrumb2']) && empty($items)) {

    $current_path = current_path();

    $element['#links'] = array(

      array('title' => t('Add breadcrumb'), 'href' => 'breadcrumb/add', "query" => array('path' => $current_path, drupal_get_destination())),

    );

  }

}

    在这里,我们直接为$element['#links']设置了一个链接。清除缓存,现在,在没有面包屑实体对象的情况下,也有上下文链接了:

图片1.png 

我们在这里面,为链接提供了一个"query"参数,它是这样设置的; 

"query" => array('path' => $current_path, drupal_get_destination())

这里面,drupal_get_destination()返回的本身就是一个数组。除了它以外,我们还提供了'path',这里的目的是,通过URL传递参数。这样,用户在添加面包屑对象的时候,就不需要输入刚才的路径了。修改文件里面的:

function breadcrumb2_add(){

  $breadcrumb = entity_get_controller('breadcrumb2')->create();

  //drupal_set_title(t('Create breadcrumb'));

  if (isset($_GET['path'])) {

    $breadcrumb->path = $_GET['path'];

  }

  $output = drupal_get_form('breadcrumb2_form', $breadcrumb);

 

  return $output;

}

粗体为我们新增的代码。这里我们直接尝试从URL获取path参数,并将它赋值给$breadcrumb->path。这样用户就不用输入路径了。

当然,还有一点不足,那就是用户对于这个路径还是可以编辑的,实际上,我们应该不允许用户编辑这个路径。当路径已经存在的情况下,就不允许编辑了。因为路径是唯一的。

function breadcrumb2_form($form, &$form_state, $breadcrumb) {

……

  $form['path'] = array(

    '#type' => 'textfield',

    '#title' => t('Path'),

    '#maxlength' => 60,

    '#default_value' => !empty($breadcrumb->path) ? $breadcrumb->path : '',

    '#weight' => -10,

  );

  if (!empty($breadcrumb->path)) {

    $form['path']['#disabled'] = TRUE;

  }

  ……

breadcrumb2_form中追加上面的粗体代码即可。这是现在的效果图:

图片2.png 

    还不错吧。还有值得改进的地方,实际上Drupal本身的面包屑,总是存在的。所以我们这里的上下文链接,不应该叫做添加面包屑。此外,删除面包屑,对我们来说也没有什么用,所以删除链接,也可以不要。最终,我们将编辑、添加面包屑,统一成为配置面包屑。下面是修改后的代码。

/**

 * Implements MODULE_preprocess_HOOK().

 */

function breadcrumb2_preprocess_breadcrumb(&$variables) {

  if (user_access('administer breadcrumbs') && user_access('access contextual links')) {

    $contextual_links_element   =    array(

      '#contextual_links' => array(

        'breadcrumb2' => array('breadcrumb', array('0')),

      )

    ); 

 

    $contextual_links = array(

      '#type' => 'contextual_links',

      '#contextual_links' => $contextual_links_element['#contextual_links'],

      '#element' => $contextual_links_element,

    );

    $variables['contextual_links'] = drupal_render($contextual_links);

  }

}

 

 

/**

 * Implements hook_contextual_links_view_alter().

 */

function  breadcrumb2_contextual_links_view_alter(&$element, &$items) {

  if (isset($element['#contextual_links']['breadcrumb2']) && empty($items)) {

    $current_path = current_path();

    $breadcrumb = breadcrumb2_load_by_path($current_path);

    if (!empty($breadcrumb)) {

      $contextual_links_element['#contextual_links']['breadcrumb2'] = array('breadcrumb', array($breadcrumb->bid));

      $element['#links'] = array(

        array('title' => t('Config breadcrumb'), 'href' => 'breadcrumb/' . $breadcrumb->bid . '/edit', "query" => drupal_get_destination()),

      );

    }

    else {

      $element['#links'] = array(

        array('title' => t('Config breadcrumb'), 'href' => 'breadcrumb/add', "query" => array('path' => $current_path, drupal_get_destination())),

      );

    }

  }

}

我们这里只是构建了一个不存在的上下文链接,相当于占位符吧,然后在hook_contextual_links_view_alter里面,模拟出来上下文链接。

还有一个很小的问题,在IE8里面,鼠标常常放不到这个链接上,快移上去时,链接就会消失。后来我想到了一个办法,外面又加了层div,并为div设置了高度。这是修改后的代码:

<?php if (!empty($breadcrumb)): ?>

<div class="breadcrumb-wrapper contextual-links-region">

  <h2 class="element-invisible">   <?php print t('You are here'); ?>  </h2>

   <?php if (!empty($breadcrumb)): ?> 

    <div style='height:10px'> <?php print $contextual_links; ?> </div>

  <?php endif; ?>

  <?php //print drupal_render($contextual_link); ?>

  <div class="breadcrumb"> <?php print implode(' » ', $breadcrumb); ?> </div>

</div>

<?php endif; ?>

这里面可是有个bug哦,细心的朋友一眼可能就看出来了。到目前为止,我们已经完成了breadcrumb2模块项目的beta2版里面的所有代码了。同时还解决了Views的一个问题。我们这里也顺带的介绍一下,从beta2beta4里面所解决的问题。以及在实践当中遇到的其它问题。


Drupal版本: