某些原因,要用一下drupal。drupal是套很好的cms系统,当然也可以做blog用。优点自然不用说了,功能强,灵活,缺点也很显然。眼前就有三条:
1 效率太低,四处都是查询,一个页面打开估计没30次查询也要有20次。
2 插件水平差距太大。写成什么样的都有,快的慢的,好的坏的,虽然看起来大体一致,不过差距还是很大的。
3 blog这个模块只能算入门,距离可用还差很多。关键就是没有模版。单用户的时候好办,多用户的时候,就麻烦了。
我下面做的事情就是再试图解决多人blog模版这个问题。当然了,我也懒得花太多时间在上面,所以同样犯了“插件水平差距太大”的错误,不过好处是效率还不算太白痴,界面虽然也不怎么样,但是至少能用。反正如果你正好碰上这个问题,不妨参考一下。我是在drupal.org上翻了个遍也没找到合适的东西。
一 原理
所谓自定义模版,其实就是自定义css,无论是mt还是wp的模版,其实在页面结构上是确定的。两栏还是三栏都是确定的,除了整个换模版的结构,一般不好改,当然也没必要改。我们也按照这个思路,做一个常用的两栏模版。想更复杂其实也不难,不过就要改动blog.module这个模块了,为了维护和升级方便,我不想动这个代码。
那么我们做的就是,提供用户可以输入的html代码,作为左栏,提供用户可以修改的css代码,以便修改样式。因为左栏是html代码,用户就可以随意的往里面加入div的块,于是就可以方便的增加blogroll或是日历或是什么其他需要的功能。通过样式又可以调节这些模块的风格,这就基本够用了。
那么我们要做的事情其实就是:
1 提供一个模块
2 将这个模块作为block装入blog和node页面
虽然简单,但是并不简陋。要知道,wp的著名插件sidebar的原理也是这样的,我只是让他简单一点,界面简陋一点,但是功能可不差什么了。
二 模块
drupal的模块挺让人头疼,因为方法太多,四处都是回调函数,初看比较复杂。其实简单用几个方法就能完成了。恩,我的方法应该是比较笨,不正统的,但是的确能用。也好理解,所以我暂时也没打算改。
首先要注意的是hook这个词,在真正写函数的时候,要被写成模块的名字。比如说你写test.module,那么下面所有hook_的地方,都应该被写做test_。这样就对了。
我们要知道的几个回调函数是:
hook_help($section)
这个函数是为了让你的模块能出现在admin/modules的列表中。
hook_perm()
这个是为了定义访问权限
hook_access($op, $node)
让权限在admin/access control里面可以被分配给用户。
hook_block($op='list', $delta=0)
这个是真正生成block代码的地方了。重点。
行了,知道这4个函数,我们就可以开始开发了。
我把这个模块名字叫做yxsidebar.module (银杏sidebar,哈哈)
于是我的help函数就是这个样子的:
function yxsidebar_help($section)
{
switch ($section) {
case 'admin/modules#description':
return t('blog sidebar for Drupal.');
}
}
这样,在模块列表里面就能看到叫做yxsidebar,描述是“blog sidebar for Drupal.”的模块了,可以启用或是禁止。
然后就是
function yxsidebar_perm() {
return array('view style', 'edit style');
}
我只定义了浏览和编辑两种权限。具体用途后面说。
重头戏
yxsidebar__block($op='list', $delta=0)
代码长,不一一解释,只说需要注意的。
if(arg(0)=='node')
{
//if this node type is a blog ? and who owner this blog?
$sqlstr="select uid from node where nid=".arg(1)." and type='blog'";
$node= db_fetch_object(db_query($sqlstr));
$uid=$node->uid;
}
else if(arg(0)=='blog')
{
$uid=arg(1);
}
这个目的是只让我们定义的模版在blog相关的页面才出现。
blog相关的页面特点是,路径中包含了/blog/的,和数据库中type为blog的node。
所以需要到数据库做一次SELECT,确定node是否为blog类型。这地方就犯了我最开始说的第一个毛病--查询次数太多,降低效率,但是也没别的办法啊。这种“一切皆是node”的架构最大的缺陷大概就是这里了。我相信应该还有更简单的判断方法,但是我不知道⋯⋯这也是最开始说的问题2的原因。不是所有开发者都能把那么厚的文档熟读的。很多时候,我只是为了简单的做个功能,并没打算做drupal专家。
闲话说完,继续。
if(is_numeric($uid))
{
$styles= db_fetch_object(db_query('SELECT * from blogstyle where uid='.$uid.' limit 1;'));
if($styles)
{
$block['content'] .="\r\n".''."\r\n";
$block['content'] .="\r\n
\r\n";
}
}
}
这个简单,是接着上面的,就是如果$uid是数字,也即为blog相关页面,那么就从数据库取出这个用户的模版,放在block的content里面。在我这个例子中,数据库里面存放的只是css文件的名字。如果存放css代码,原理也类似,需要的话,自己改吧。
下面的代码比较长,简化一下就是:
if (user_access('edit style'))
{
if(arg(2)=='edit')
{
}
else if(arg(2)=='save')
{
}
}
这样的。用法就是,先判断是否有edit权限(记得hook_perm()里面的定义了吗?),如果有的话,就做一些动作。我在这里定义了form,用户可以提交修改。这个手法可能也不太正宗。不过目的是达到了。
就这么简单。如果进一步发挥,可以让界面更好一点。比如定义几个块,让用户直接选择,而不是和我这样直接用textarea直接写代码。这些都是锦上添花的事情了,也不难。按照这个原理,相信很容易做出来。
完整的代码放在下面了。yxsidebar.install我懒得写了,反正就是建个库存东西,按照自己的需要来吧。没什么难的。
yxsidebar.module