<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Terrysco&#039;s Blog &#187; CMS/FrameWork</title>
	<atom:link href="http://www.terrysco.com/node/category/cmsframework/feed" rel="self" type="application/rss+xml" />
	<link>http://www.terrysco.com</link>
	<description>仅关注于互联网行业， Linux平台开发。</description>
	<lastBuildDate>Sat, 22 May 2010 10:50:29 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.3</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>CodeIgniter 入门</title>
		<link>http://www.terrysco.com/node/codeigniter-introduction.html</link>
		<comments>http://www.terrysco.com/node/codeigniter-introduction.html#comments</comments>
		<pubDate>Mon, 29 Mar 2010 05:20:11 +0000</pubDate>
		<dc:creator>terrysco</dc:creator>
				<category><![CDATA[CMS/FrameWork]]></category>
		<category><![CDATA[codeigniter]]></category>

		<guid isPermaLink="false">http://www.terrysco.com/?p=331</guid>
		<description><![CDATA[终于花了1个半星期的时间看完了“CodeIgniter 1.7”这本书，300多页，不过内容还算丰富。从web开发的各个方面介绍了CodeIgniter这个PHP框架，章节的安排跟那本“Pro Drupal Development”类似。看完本书后，感觉codeigniter确实能弥补一些目前的PHP框架开发现状，目前来说基于PHP的CMS比较全，国外流行的有drupal，joomla，CMSMS等等，国内的就更数不胜数了。但提到framework，大家都想到zend framework，研究过一段时间这个框架，感觉过于庞大了，至于剩下的cakePHP，thinkPHP，国内的FleaPHP都没有涉及过，第一个接触的正式PHP框架（正式是针对drupal来说）就是CodeIgniter了。
使用drupal2年多，已经身心疲惫。总是感觉还不是那么的灵活，性能还不是那么的好，总想对它控制得更多，但我们能做的只有hook。不可否认，drupal在快速搭建一些中小型站点确实是不错的选择，模块很多，社区很活跃，但是如果用来开发一些大型的应用就显得力不从心了，比如我们开发一个万人活跃用户的SNS社区，一个多应用服务器架构的系统。drupal本身是面向过程的PHP通过HOOK机制组织起来的，这时我们就迫切需要一款MVC的面向对象设计的框架。codeigniter正是如此。
比较喜欢CI（codeigniter的简称）的一些设计理念，第一个就是从不强迫用户，CI为开发者提供了很多功能（helper，plugin，library等等），方便开发者，但它不强迫你使用这些功能，你完全可以自定义开发自己的功能模块，甚至可以很方便的集成第三方工具进来，不像drupal，你必须对drupal机制要很了解，才能做一些比较深入的工作。另外，CI的定制性很高，你可以参考CI的文档对其任意定制，足以迷惑用户是不是CI开发出来的站点。
网上有一个老外做的视频，20分钟用CI搭建一个blog系统，虽说有些夸张，但功能也太简陋了，不管是安全性还是UE都没有考虑太多，我做过一个测试，3-4个小时开发出来一套多用户blog系统是完全可行的。
此外，CI为我们提供了很多类库，涵盖的功能如下：

文件下载
邮件发送，可包含附件
表单
FTP
分页

。。。
CodeIgniter，值得学习。
]]></description>
		<wfw:commentRss>http://www.terrysco.com/node/codeigniter-introduction.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>关于drupal架构的思考</title>
		<link>http://www.terrysco.com/node/drupal-extension.html</link>
		<comments>http://www.terrysco.com/node/drupal-extension.html#comments</comments>
		<pubDate>Fri, 11 Dec 2009 09:58:11 +0000</pubDate>
		<dc:creator>terrysco</dc:creator>
				<category><![CDATA[CMS/FrameWork]]></category>
		<category><![CDATA[drupal]]></category>

		<guid isPermaLink="false">http://www.terrysco.com/?p=289</guid>
		<description><![CDATA[自从drupalchina推荐我的blog后，很多drupal的开发者和我讨论drupal的性能，drupal的缺陷，大有感触。
很多人都说drupal站点不适合扩展，或者简单的做到数据库和代码分离后就茫然了。最近参考了很多软件和web架构的书，反过来对drupal这个系统做了一些关于架构扩展的思考。
以自己现有水平来看，drupal的瓶颈似乎在PHP代码执行层面。网上说使用APC加速可以大大加强drupal的性能，自己还没有手动进行测试，所以没有发言权。但目前在自己使用过程中，还是看到drupal一些小尴尬。
drupal的缓存系统比较简单，只是对匿名用户（因为匿名用户访问页面变更比较少）进行页面缓存，并且是以数据库的形式进行缓存。直接序列化页面到cache_page表中，这种性能可想而知，如果对百万级的访问量来说，db将会是个噩梦。
drupal用apache的rewrite模块实现了简洁链接，伪静态页面是提高了SEO效果，但是针对生成静态页面来说，还是比较困难的。另外，drupal的代码可以更加精简，否则为了强大的扩展性损失大幅性能也是不可取的。
有人说代码和架构扩展没有关系（忘记哪位大牛说的），其实我不是很赞同这句话，代码和数据库刚开始的设计决定或者制约了很多后面需要扩展的条件，比如水平划分数据库表的时候，最好是选取primary key，但是这个字段最好不是auto_increment的（道理很容易想到），再比如数据库抽象层的代码如果做memcache缓存，好修改吗？
很多时候，代码级别制约扩展性的很大一个因素就是联合查询，因为在做垂直划分数据库的时候，分离的都是一些关联性不大，并且不会牵扯到联合查询的库表，但drupal很多地方都使用的inner join（几乎每个模块都能看到）。当用户并发数越来越大，服务器最大的压力来源于数据库，这时，有些朋友就说了”负载均衡“啊。
没有那么简单，首先我们考虑基于重定向的负载均衡，多做几个后端服务器，使用RR或者简单随即抽取机制来轮流使用服务器，drupal和其他站点不同的一点小小特性就是唯一入口index.php，也就是说在这个文件我们可以写入一些代码，实现重定向的负载均衡，这点是比较合适的。或者您为了避免不是真正的压力平衡，可以使用DNS负载均衡，这样下来，稍微大点的数据量我们勉强顶得住了。
从水平划分的方面来看，首先最大的表应该是drupal的node表，nid字段是primary key,并且auto_increment的，这就很难进行分表存储。另外就算使用了一些别的算法，分N个表出来存储node，问题是如果使那些众多的node相关操作代码使用不会出问题？
另外一种做法就是使用ngnix的反向代理功能，很多java的开发者叫分布式。就算后端服务器性能差异，我们还是可以通过配置文件来决定权重，能者多得的方式，让每个机器发挥到极限。还可以考虑的方式就是使用apache加载我们定义的lua脚本，匹配select和insert，update，delete等字符串，用来区分属于何种sql查询，进一步实现读写分离。不过在机器之间的数据同步也是个麻烦的事情，我没有在运维方面有多少经验，最多就是使用过rsync。
分析种种情景，使用drupal的用户不要担心，只要我们想的到，可扩展的办法还是很多的。性能决定在你自己手里。
]]></description>
		<wfw:commentRss>http://www.terrysco.com/node/drupal-extension.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>定制wordpress的文章发布</title>
		<link>http://www.terrysco.com/node/wordpress-meta-box.html</link>
		<comments>http://www.terrysco.com/node/wordpress-meta-box.html#comments</comments>
		<pubDate>Thu, 05 Nov 2009 04:04:16 +0000</pubDate>
		<dc:creator>terrysco</dc:creator>
				<category><![CDATA[CMS/FrameWork]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.terrysco.com/?p=287</guid>
		<description><![CDATA[wordpress在发布文章的时候，已经集成了很多特性，比如tinyMCE这个可视化编辑器，文章标签（tags），别名（alias），以及分类（taxonomy）。但对于一个基于wordpress的项目，我们仍然需要对其高度定制，wordpress为我们提供了add_meta_box，来优雅的解决这个问题。
用起来比较简单，就6个参数，其中第三个参数为callback。我们可以在这个callback中设置一些输出信息，或者一个表单，最常用的还是后者。比如我们设置一个textarea的文本区域，用来保存一些用户输入的信息，这样用户发布这个post或者page的时候，这个信息就会保存到postmeta表里。其次，我们可以使用get_post_meta来获取这个数据。说到这里，有必要简单提下wordpress的表结构。
不像drupal那么复杂，wordpress主要的内容信息其实就两个表，一个post表，一个postmeta表，前者存放用户发布的基本内容，比如一篇blog，后者存放这个内容的一些附加信息，比如我们刚才定制的那个textarea。
最后，这里说下我碰到的一个问题以及自己的解决办法。在使用add_meta_box的时候，我们只是给post这个表单加入了一些输入控件，如果要处理文件的上传，或者使用curl等库来处理更高级的http操作，就出现问题了。因为form这个表单本身在wordpress中就定义好了，我们知道如果上传文件，form表单必须设置enctype = &#8220;multipart/form-data&#8221;属性，但默认的是没有的。google大叔告诉我很多人直接修改了wordpress的core，但我觉得这不是一个好的处理方式，我的解决办法是加入一段javascript来动态修改。
window.onload = function() {
	var form = document.getElementById(&#8221;post&#8221;);
	form.enctype = &#8220;multipart/form-data&#8221;;
};
这段javascript可以替换为更好的jquery代码，因为jquery等很多javascript类库已经集成到wordpress里面。目前能想到的就是这种方式，或许我还不够了解wordpress的机制？
]]></description>
		<wfw:commentRss>http://www.terrysco.com/node/wordpress-meta-box.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>初涉wordpress开发</title>
		<link>http://www.terrysco.com/node/wordpress-starting.html</link>
		<comments>http://www.terrysco.com/node/wordpress-starting.html#comments</comments>
		<pubDate>Mon, 02 Nov 2009 10:23:30 +0000</pubDate>
		<dc:creator>terrysco</dc:creator>
				<category><![CDATA[CMS/FrameWork]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.terrysco.com/?p=285</guid>
		<description><![CDATA[近期涉及到wordpress-MU版本的开发工作，因为用户对其插件buddypress比较感兴趣。看了两天的文档，感慨wordpress文档的匮乏。。。
除了少的可怜的官方文档，基于codex系统，很多页面都没有书写外，自己down了一份plugin development的pdf，看完这个pdf才有点插件开发的感觉。写了4-5个小插件，熟悉了下wordpress的hook（wp中称作action和filter）。感觉还是不如drupal的模块优雅和灵活，但定制一个系统还是比较简单的，最大的痛苦就是wordpress的api函数太多，而很多都没有文档，不知道该如何选择，看了很多sample，用的还都不一样，版本之间留有差异性，不像drupal，5.x和6.x之间分别保持统一。
目前看来，一个buddypress新建一个用户，数据库中会多出8个表，这个恐怖的事实在网上已经有商业插件解决，不知道这个项目到底是怎么回事？
另外，视频方面采用了vimeo，开发和调试阶段颇为麻烦，因为国内的防火墙墙掉了很多应用，vimeo也不例外，使用vpn虽然解决了这个问题，但文档和wordpress一样少的可怜。
经过5天的google和编码，还算有点收获，过几天不忙了整理点文档共享给wordpress的插件开发者们。感慨：好的开源项目，如果文档不完善，依然是一件痛苦的事情。
]]></description>
		<wfw:commentRss>http://www.terrysco.com/node/wordpress-starting.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>给drupal批量导入外部数据</title>
		<link>http://www.terrysco.com/node/drupal-colletion-info.html</link>
		<comments>http://www.terrysco.com/node/drupal-colletion-info.html#comments</comments>
		<pubDate>Fri, 16 Oct 2009 12:37:11 +0000</pubDate>
		<dc:creator>terrysco</dc:creator>
				<category><![CDATA[CMS/FrameWork]]></category>
		<category><![CDATA[drupal]]></category>

		<guid isPermaLink="false">http://www.terrysco.com/?p=276</guid>
		<description><![CDATA[很多时候，我们想给自己的drupal站点批量导入节点数据，其中包括很多方法，例如csv格式文件的导入，通过别的站点抓取到得信息，整合别的系统时，相互数据的迁移都要用到这些内容。我们建立一个简单的模型，只考虑节点基本数据，不考虑其他因素（比如节点图片，节点术语分类等等），将模型简单化有助于我们解决问题。
以拿抓取页面为例，我们使用正则表达式过滤出需要的信息后，将其存放在一个一维关联数组中，其中键对应数据库中的节点字段，比如title，body，name。。。然后我们手动调用node_submit方法，将一维数组传进去，这个方法会对我们的数组做一些存表之前的工作，我们直接可以在api.drupal.org查看这个方法的代码。
&#60;?php
function node_submit($node) {
  global $user;

  // Convert the node to an object, if necessary.
  $node = (object)$node;

  // Auto-generate the teaser, but only if it hasn't been set (e.g. by a
  // module-provided 'teaser' form item).
  if (!isset($node-&#62;teaser)) {
    $node-&#62;teaser = isset($node-&#62;body) ? node_teaser($node-&#62;body, isset($node-&#62;format) ? [...]]]></description>
		<wfw:commentRss>http://www.terrysco.com/node/drupal-colletion-info.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>剖析ubercart</title>
		<link>http://www.terrysco.com/node/drupal-ubercart.html</link>
		<comments>http://www.terrysco.com/node/drupal-ubercart.html#comments</comments>
		<pubDate>Tue, 04 Aug 2009 10:25:05 +0000</pubDate>
		<dc:creator>terrysco</dc:creator>
				<category><![CDATA[CMS/FrameWork]]></category>
		<category><![CDATA[drupal]]></category>

		<guid isPermaLink="false">http://www.terrysco.com/?p=240</guid>
		<description><![CDATA[ubercart是一套很好的搭建电子商务平台代码，被很好的以模块形式应用到了drupal上，接合drupal的强大功能很容易生成电子商务站点。
下载了最新版本的模块看了看，代码量确实巨大。要先学会怎么用，再去看代码我想工作效率会更高，所以启用模块建了几个产品试试，购物车和付费平台什么的功能都走通了之后开始挑几个重要的代码段看了看。因为我要实现一个充值后增加userpoints积分的功能，找了半天终于找到一个相关模块，但是问题很多，issue页面也有人提出了类似的问题。没办法只能靠自己了，了解product模块和feature相关特性后，很轻松的就找到了问题所在。大家需要类似功能的可以参考下。
http://drupal.org/node/514534
解决办法在评论里面，不过我没有测试，只是看到代码流程没有问题了。首先建立一个feature，将产品节点绑定到这个feature里面，再实现order这个hook，在里面判断当订单完成状态后，使用userpoints模块的接口给购买用户增加分数。至于points的分类和数目完全可以自己在后台设置，还是不错的功能，只是纳闷作者为什么这么粗心，错了一个变量，错了一个表名。
]]></description>
		<wfw:commentRss>http://www.terrysco.com/node/drupal-ubercart.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>快速从drupal5升级到drupal6</title>
		<link>http://www.terrysco.com/node/from-drupal5-to-drupal6.html</link>
		<comments>http://www.terrysco.com/node/from-drupal5-to-drupal6.html#comments</comments>
		<pubDate>Sat, 01 Aug 2009 07:00:32 +0000</pubDate>
		<dc:creator>terrysco</dc:creator>
				<category><![CDATA[CMS/FrameWork]]></category>
		<category><![CDATA[drupal]]></category>

		<guid isPermaLink="false">http://www.terrysco.com/?p=236</guid>
		<description><![CDATA[从drupal5升级到drupal6的必要性有必要先说明下（听着有点绕口）：一年前drupal6刚出来的时候大家都不建议升级，因为最大的问题就是相关模块支持太少，但到现在drupal6已经相当成熟，包括更严格的菜单路径映射功能（drupal5的时候菜单系统出现很多安全问题），更好的jquery加强站点UE，以前设置权重值很是麻烦，而现在只要进行拖动保存后就可以了，另外很多api更加细化，人性化和简单化。BTW，能升级到windows7的用户赶紧升级吧，因为比XP好用很多，我没有枪手嫌疑，因为我是个忠实的Linux用户。
关于升级服务器端部署问题这篇文章将不涉及，前面文章有介绍过，并且我记得在drupal.org上有篇文章是专门介绍如何从drupal5直接升级到drupal6的，我这里只是介绍模块开发人员要学习和参考的东西。
首先，菜单系统。我想这是在drupal6中最大的变化，首先$items这个序列化数组的键完全不同了，从callback 和 callback arguments变成了page callback，access也变成了access_callback以及access_arguments（包括title属性），这就意味着开发人员可以更好的定制drupal的菜单系统。而且drupal6引入的path arguments更好的规范了drupal的动态菜单，配合load后缀函数方面页面传递参数，这里改动比较复杂，大家参考官方文档。
数据库层改动不大，接下来说说form api几个地方的改动，几个hook的参数发生了改变，form_alter , form_validate, form_submit，第一个变成了三个参数，最后一个参数才是form_id，并且为了性能问题，因为之前form_alter要检测所有的form，加入了modulename_form_formname_alter函数。第二个参数数组发生了变化，现在都用$form_state['value']['element_name']判断，其中element_name是form数组中定义的表单元素。第三个提交后返回地址更加方便，直接修改$form['redirect']的值为内部链接就可以了，不用drupal_goto函数（其实也是对drupal_goto的再次包装），不过记得传递进来的是地址引用，而不是值。
在使用上来看，很多模块都更新了，操作更加方面，所以建议大家升级到drupal6系统。
]]></description>
		<wfw:commentRss>http://www.terrysco.com/node/from-drupal5-to-drupal6.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>drupal的WAP页面</title>
		<link>http://www.terrysco.com/node/drupal-wap.html</link>
		<comments>http://www.terrysco.com/node/drupal-wap.html#comments</comments>
		<pubDate>Thu, 16 Jul 2009 03:58:06 +0000</pubDate>
		<dc:creator>terrysco</dc:creator>
				<category><![CDATA[CMS/FrameWork]]></category>
		<category><![CDATA[drupal]]></category>

		<guid isPermaLink="false">http://www.terrysco.com/?p=223</guid>
		<description><![CDATA[要给站点提供一些wap访问的简单页面，数据在drupal的db中已经有了，网上找了找没有相关模块，只能自己动手了。
在站点根目录下创建文件wap.php

&#160;
$output = '';
&#160;
switch &#40;$_GET&#91;'op'&#93;&#41; &#123;
  case 'list':
    $pid = &#40; isset&#40;$_GET&#91;'id'&#93;&#41; ? intval&#40;$_GET&#91;'id'&#93;&#41; : '' &#41;;
&#160;
    $result = // fetch from database.
&#160;
    $output .= '';
    foreach &#40;$result as $key =&#38;gt; $val&#41; &#123;
      $output .= '
&#160;
';
   [...]]]></description>
		<wfw:commentRss>http://www.terrysco.com/node/drupal-wap.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>【转载】drupal的性能问题</title>
		<link>http://www.terrysco.com/node/drupal-performance.html</link>
		<comments>http://www.terrysco.com/node/drupal-performance.html#comments</comments>
		<pubDate>Tue, 09 Jun 2009 18:26:54 +0000</pubDate>
		<dc:creator>terrysco</dc:creator>
				<category><![CDATA[CMS/FrameWork]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.anyliv.com/www.terrysco.com/?p=97</guid>
		<description><![CDATA[<p>原文地址：&#160;<a href="http://www.bloggern.com/3577.html">http://www.bloggern.com/3577.html</a>&#160;</p><p><span class="Apple-style-span" style="font-family: Verdana; font-size: 14px; line-height: 21px; ">我因为工作原因，曾经对Drupal做过比较全面的测试。当时的环境是双服务器（DB server+Web Server），硬件配置都是单CPU+4G。数据库里面有几千条记录。用JMeter对各种情况下（开/关各种cache模块，logged user/anonymous user）不同页面的读取和写入操作都进行过测试。&#160;<br />...</p></span>
]]></description>
		<wfw:commentRss>http://www.terrysco.com/node/drupal-performance.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>关于drupal区块的小问题</title>
		<link>http://www.terrysco.com/node/drupal-block.html</link>
		<comments>http://www.terrysco.com/node/drupal-block.html#comments</comments>
		<pubDate>Tue, 02 Jun 2009 18:32:01 +0000</pubDate>
		<dc:creator>terrysco</dc:creator>
				<category><![CDATA[CMS/FrameWork]]></category>
		<category><![CDATA[drupal]]></category>

		<guid isPermaLink="false">http://www.anyliv.com/www.terrysco.com/?p=96</guid>
		<description><![CDATA[<p>drupal模块开发中经常用到区块的概念，将一些相关数据放到区块中，配合权限验证，将用户能看到的信息以区块的形式展示到用户浏览器中。不过区块是跟节点无关了，如果要根据当前节点页面的特性针对性的在区块中显示内容，我的做法是：</p><p>if (arg(0) == 'node' &#38;&#38; is_numeric(arg(1)) { // 初步设想是仅仅当路径是' node / 3 ',类似这样的地址时显示</p><p>&#160; $node = node_load(arg(1));</p>...
]]></description>
		<wfw:commentRss>http://www.terrysco.com/node/drupal-block.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
