« 找个咖啡厅做办公室 | Main | drupal 在 php5.2.0 下session丢失的处理办法 »

给drupal增加多用户自定义模版的功能

作者:virushuo 发表于 2007-02-08 12:02 最后更新于 2007-02-08 13:02
版权声明:按照by-nc-sa的cc协议可转载,拒绝采用“独家” 授权媒介(含网站和平面媒体)转载、引用、链接,除非获得本人许可。转载时请务必以超链接形式标明文章原始出处和作者信息及本声明。


某些原因,要用一下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".$styles->template."\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

相关文章:
blog comments powered by Disqus
CC License. Some rights reserved.
署名·非商业用途·保持一致
本站之所有未作特别说明的内容均使用 创作共用协议.
POWERED_BY_MT_3.2