我们这个模块,是用来设置页面上面的面包屑的,开发了这么多,我们看看如果通过我们的面包屑实体来设置面包屑。向module文件添加以下代码:
/**
* Implements hook_page_alter().
*/
function breadcrumb2_page_alter() {
// See if current page has path breadcrumbs.
$breadcrumbs = drupal_get_breadcrumb();
$current_path = current_path();
$breadcrumb2 = breadcrumb2_load_by_path($current_path);
if(empty($breadcrumb2)){
return;
}
//$breadcrumb2 = breadcrumb2_load(1);
$wrapper = entity_metadata_wrapper('breadcrumb2', $breadcrumb2);
$breadcrumb_links = $wrapper->link->value();
foreach($breadcrumb_links as $breadcrumb_link){
$breadcrumbs[]= l($breadcrumb_link['title'], $breadcrumb_link['url']);
}
//print debug($breadcrumb_links);
// Set breadcrumbs for current page if it exists.
if ($breadcrumbs) {
drupal_set_breadcrumb($breadcrumbs);
}
}
这里面我们实现了hook_page_alter钩子,这个方式借鉴于path_breadcrumb模块,当然,我们也可以通过hook_preprocess_page来设置, crumbs模块里面有这种方式的实现。我们来看看这个钩子函数里面的代码,首先,我们根据当前路径,获取到面包屑实体$breadcrumb2;这里面我们对$breadcrumb2使用entity_metadata_wrapper做了封装,这样我们就可以方便的读取到实体里面字段link的数组了,这样做的好处是,不用考虑语言问题;之后对$breadcrumb_links数组进行循环,将里面的链接追加到当前面包屑数组$breadcrumbs里面;最后使用drupal_set_breadcrumb设置面包屑。
接下来,来看一下函数breadcrumb2_load_by_path的实现代码:
/**
* Fetch a breadcrumb object.
*
* @param $path
* Internal path.
* @return
* A fully-loaded $breadcrumb object or FALSE if it cannot be loaded.
*
* @see breadcrumb2_load_multiple()
*/
function breadcrumb2_load_by_path($path) {
$breadcrumbs = breadcrumb2_load_multiple(FALSE, array('path' => $path));
return reset($breadcrumbs);
}
我们直接将其委托给了breadcrumb2_load_multiple,把array('path' => $path)作为条件参数传递了过去。如果返回了面包屑对象数组,我们就使用reset将数组中的第一个对象返回。这里的逻辑非常简单,和breadcrumb2_load函数类似。不过越是简单的东西,有时候越难理解。我原来的想法是这样的,使用EntityFieldQuery,把我们的$path作为属性参数传递给它,这样EntityFieldQuery将会读取来一个包含bids的数组,我们把bids数组传递给breadcrumb2_load_multiple,获得一组面包屑对象,然后再使用reset获取第一个对象元素。
Entity API帮我们做了这些工作,为了更好的理解,我们反向追踪一下代码。
通过阅读里面的代码,我们最终找到了,SQL语句是在DrupalDefaultEntityController里面的buildQuery方法中动态构建的。有兴趣的可以看一下里面的代码。
到这里我们的面包屑实体类型就创建完毕了。当然,模块还没有写完。我们接着会写Views的集成、Rules的集成。只有当集成了Rules以后,我们这种构建面包屑的方式,才能