Recently in Software Category

Movable Type 4.3 分页改进

| No Comments
Movable Type 4.3 版本开始,官方提供了一种分页方法。解决了MT静态化爱好者们实现像各种动态Blog程序,如Wordpress那样,可以一页一页地翻到最后的心愿。

从Movable Type 4.3开始加入的分页方法,其原理是将网站首页进行静态化生成,此后翻页的第2页开始,内容使用MT-Search脚本动态生成。此功能可以在文章索引以及按日期索引上使用。

对于原教旨主义静态化控的朋友们来说,此方案难免差强人意;但是作为普通的用户,这个方案已经是一个近似于完美的方案了。(纯静态化的分页方案,网上也有相关的插件等解决方案。不过这些方案的性能热点在于发布生成这些页面的时间会非常长。相比之下此种方法通过动态访问的性能还是可以接受的,毕竟系统其它页面都是静态页面,资源的耗费在通常情况下可以接受。)据我观察一些大型网站如apple4us所使用的,猜测也是类似的解决方案(如果有误请指正)

官方的Pagination解决方案,请点击:http://www.movabletype.org/documentation/designer/pagination-static.html#pagination-in-movable-type-43

但是在我架设Blog的过程中,发现官方的分页解决方案有如下两个问题:

  • 上一页/下一页的链接,在首页是/pages/n.html这种格式,但是在从第二页开始的动态生成页面中,程序就对此链接直接生成了mt-search.cgi?xxxx=xxxx这样的链接,而不是期待中的pages/2.html。不美观同时也不利于SEO
  • 同样在从第二页开始的动态生成页面中,页码显示也不正确,只显示出了当前页的页码,而没有所有页面的页码,无法快速翻页。

于是自己针对原始版本,进行了一些小修改,解决了如上问题。

首先需要确认已经应用官方的分页方式,根据官方的文档,对模板中的 Main Index 模板做出相应修改。

然后确保已经加入Rewrite Rule。我使用的Rewrite Rule如下:(.htaccess放置于网站根目录)
RewriteEngine on

#Pagination
RewriteRule page/([0-9]+).html/?$ /cgi-bin/mt4/mt-search.cgi?IncludeBlogs=1&template_id=46&limit=3&archive_type=Index&page=$1 [L,QSA]
Pagination分页的url设置为 /page/1.html 这种格式。需要注意的是,用户需要把/cgi-bin/mt4/这个路径,需要修改为和自己blog一致的cgi路径。同时template_id也要和自己的网站设置一致。

然后我们就动手针对遇到的问题进行修改。要解决这些问题,只要修改Main Index这个模板就可以了。

MT的模板文件中,使用很多MT标签来执行一些简单的程序逻辑,首先让我们看看该问题的根源。

从这里可以发现"上一页"链接的指向。
<mt:IfPreviousResults>
<a href="<$mt:PreviousLink$>" rel="prev" onclick="return swapContent(-1);">&lt; Previous</a>&nbsp;
</mt:IfPreviousResults>
可以发现上一页/下一页的链接是由<mt:PreviousLink>以及<mt:NextLink>两个模板标签来控制的。经过测试发现这两个标签会直接输出诸如mt-search.cgi?xxxx=xxx这样的链接。

那么就要把这两个标志用指向页面的链接替换,以达到我们使用直观页面URL的效果。

通过分析下方控制第一页链接的部分,我们可以看到,链接是通过一个记录当前页链接的变量,再组合url来生成的。
<a href="<$mt:Var name="search_link"gt;<$mt:Var name="pbpage"gt;.html"><$mt:Var name="__value__"gt;</a>
这样具体解决这个问题的思路就清晰了:首先找到当前页面的页码,然后生成一个url显示出来,就可以达到我们想要的美观的分页url。

所以我们就需要在<mt:PagerBlock>里面,设置一个记录当前页码的变量。(<mt:PagerBlock是循环体,相当于程序设计语言里的for,遍历程序的所有页面)

我们只需要判断一个循环中的页面是否是当前页,然后设置一个变量即可。但是需要注意的是,我经过很多次实验,发现<mt:IfCurrentPge>这个判断条件判断的,恰恰不是CurrentPage, <mt:Else>分支下,反而是当前页面的判断,这十分奇怪。(这情况也导致出现这许多问题)

最终修改好的PreviousLink部分代码为:(该部分设置了一个变量currpage,记录当前页面号码)
 <mt:Ignore><!-- Navigation for dynamic pages (same as navigation found in the Search Results system template). --></mt:Ignore>
        <mt:IfPreviousResults>
           <mt:PagerBlock>
            <mt:IfCurrentPage>
            <mt:Else>
                <$mt:Var name="currpage" value="$__value__"$>
            </mt:IfCurrentPage>
           </mt:PagerBlock>
           <$mt:SetVar name="currpage" op="--"$>
           <a href="<$mt:Var name="search_link"$><$mt:Var name="currpage"$>.html" rel="prev" onclick="return swapContent(-1);">&lt; 上一页</a>&nbsp;
           <$mt:SetVar name="currpage" op="++"$>
        <mt:Else>
           <$mt:Var name="currpage" value=1$>
        </mt:IfPreviousResults>
随后处理并修改页码显示的部分,修改后可以正确显示当前页面以及所有页面。
      <mt:PagerBlock>
            <mt:SetVarBlock name="pbpage"><$mt:Var name="__value__"$></mt:SetVarBlock>
                <mt:If name="pbpage" ne="$currpage"><a href="<$mt:Var name="search_link"$><$mt:Var name="pbpage"$>.html"><$mt:Var name="__value__"$></a></mt:If>
            <mt:IfCurrentPage><mt:Else>
                <$mt:Var name="__value__"$><$mt:Var name="currpage" value="$__value__"$>
            </mt:IfCurrentPage>
        </mt:PagerBlock>
最后是处理下一页的链接部分:
      <mt:IfMoreResults>
        <$mt:SetVar name="currpage" op="++"$>
        &nbsp;<a href="<$mt:Var name="search_link"$><$mt:Var name="currpage"$>.html"  rel="next" onclick="return swapContent();">下一页 &gt;</a>
        </mt:IfMoreResults>
进行完这些修改后,从第二页开始的动态生成的分页页面中的链接,以及所有的页码链接,都可以显示正确了。

倘若没有耐心读完前面逐步修改与分析的结果,也可把如下完整的修改后的分页模板代码粘贴到Main Index模板中,覆盖 从 <mt:Ignore> Create pagination 开始,直到 <a href="<$mt:Link template="archive_index"$>">Archive Index</a> 这部分代码即可。

修改后的分页效果可查看我的Blog第二页的显示效果
<mt:Ignore><!-- Create pagination navigation. Condition based upon if page is statically or dynamically rendered using the search_results variable. --></mt:Ignore>
<mt:Ignore><!-- pagination url mod by CNBorn, cnborn.net --></mt:Ignore>
<mt:SetVarBlock name="pagination_navigation">
    <mt:If name="search_results">
        <mt:Ignore><!-- Navigation for dynamic pages (same as navigation found in the Search Results system template). --></mt:Ignore>
        <mt:IfPreviousResults>
           <mt:PagerBlock>
            <mt:IfCurrentPage>
            <mt:Else>
                <$mt:Var name="currpage" value="$__value__"$>
            </mt:IfCurrentPage>
           </mt:PagerBlock>
           <$mt:SetVar name="currpage" op="--"$>
           <a href="<$mt:Var name="search_link"$><$mt:Var name="currpage"$>.html" rel="prev" onclick="return swapContent(-1);">&lt; 上一页</a>&nbsp;
           <$mt:SetVar name="currpage" op="++"$>
        <mt:Else>
           <$mt:Var name="currpage" value=1$>
        </mt:IfPreviousResults>
        <mt:PagerBlock>
            <mt:SetVarBlock name="pbpage"><$mt:Var name="__value__"$></mt:SetVarBlock>
                <mt:If name="pbpage" ne="$currpage"><a href="<$mt:Var name="search_link"$><$mt:Var name="pbpage"$>.html"><$mt:Var name="__value__"$></a></mt:If>
            <mt:IfCurrentPage><mt:Else>
                <$mt:Var name="__value__"$><$mt:Var name="currpage" value="$__value__"$>
            </mt:IfCurrentPage>
        </mt:PagerBlock>
        <mt:IfMoreResults>
        <$mt:SetVar name="currpage" op="++"$>
        &nbsp;<a href="<$mt:Var name="search_link"$><$mt:Var name="currpage"$>.html"  rel="next" onclick="return swapContent();">下一页 &gt;</a>
        </mt:IfMoreResults>
    <mt:Else>
        <mt:Ignore><!-- Navigation for statically published page. --></mt:Ignore>
        <mt:If name="archive_template">
            <$mt:ArchiveCount setvar="total_entries"$>
        <mt:Else>
            <$mt:BlogEntryCount setvar="total_entries"$>
        </mt:If>
        <mt:Ignore><!-- If blog contains more entries than the number of entries to display per page. --></mt:Ignore>
        <mt:If name="total_entries" gt="$entries_per_page">
            <mt:Ignore><!-- Set the total number of entries to iterate through the pages. --></mt:Ignore>
            <mt:Ignore><!-- IF total entries divided by entries per page is a whole number. --></mt:Ignore>
            <mt:If name="total_entries" op="%" value="$entries_per_page" eq="0">
                <mt:Ignore><!-- Set total pages to total entries divided by entries per page. --></mt:Ignore>
                <$mt:Var name="total_entries" op="/" value="$entries_per_page" setvar="total_pages"$>
            <mt:Else>
                <mt:Ignore><!-- Get the remainder when dividing total entries by entries per page. --></mt:Ignore>
                <$mt:Var name="total_entries" op="%" value="$entries_per_page" setvar="remainder"$>
                <mt:Ignore><!-- Subtract remainder from total entries. --></mt:Ignore>
                <$mt:Var name="total_entries" op="-" value="$remainder" setvar="total_entries"$>
                <mt:Ignore><!-- Determine total pages by dividing total entries (minus remainder) by entries per page. --></mt:Ignore>
                <$mt:Var name="total_entries" op="/" value="$entries_per_page" setvar="total_pages"$>
                <mt:Ignore><!-- Add one page to handle the remainder of entries. --></mt:Ignore>
                <$mt:SetVar name="total_pages" op="++"$>
            </mt:If>
            <mt:Ignore><!-- Loop through total pages, creating links to all but the first page (which is the current page). --></mt:Ignore>
            <mt:For from="1" to="$total_pages" step="1">
            <mt:If name="__first__">
                <$mt:Var name="__index__"$>
            <mt:Else>
                <a href="<$mt:Var name="search_link"$><$mt:Var name="__index__"$>.html"><$mt:Var name="__index__"$></a>
            </mt:If>
            </mt:For>
            <mt:Ignore><!-- Hard-coded link to the next page (page 2). --></mt:Ignore>
            &nbsp;<a href="<$mt:Var name="search_link"$>2.html" rel="next">下一页 &raquo;</a>
        </mt:If>
    </mt:If>
</mt:SetVarBlock>
<mt:Ignore><!-- Strip space and trim navigation code. --></mt:Ignore>
<$mt:Var name="pagination_navigation" strip=" " trim="1" setvar="pagination_navigation"$>

<div class="content-nav">
<mt:Ignore><!-- Output variable if exists. --></mt:Ignore>
<$mt:Var name="pagination_navigation" strip=" " trim="1" setvar="pagination_navigation"$>
<mt:If name="pagination_navigation">
    <div class="pagination-navigation">
        <$mt:Var name="pagination_navigation"$>
    </div>
</mt:If>
    <a href="<$mt:Link template="archive_index"$>">历史归档</a>
</div>

Bugzilla中针对不同产品的权限设定

| No Comments
Bugzilla是一个经典的软件缺陷追踪工具,最初版本由Netscape开发,1998年遵循Mozilla Public License协议公开源代码。Bugzilla作为功能强大的Bug Tracking系统,在无数的商业/非商业组织和项目中得到广泛的应用。

Bugzilla 系统中默认的设计是可将所有的信息对任何人开放,但是针对用户应用需求的不同,可以针对不同产品设置不同的权限设定。可以适用于如:在一个大公司的多个软 件项目组,通过一个全公司的Bugzilla系统来追踪各个项目的Bug,各个组之间的人员并不能查看或编辑其它组的内容等类似情况。

事实上Bugzilla 网站上的手册里针对此部分有很详细的说明,但是我在使用中发现,互联网上还没有对此进行介绍的较为详细的文章,同时如果没有通过实际的例子来将设置方法加 以展示的话,整个设置和对照英文文档的过程还是让人感觉晦涩及难以理解。所以本篇文章将以Bugzilla系统应用中的实例来讲解下如何对不同产品的权限 进行设定。

(本篇文章的内容在Bugzilla 3.2,3.2.3中测试完成,Bugzilla后续版本可能会对此部分功能进行变更,请在使用及部署中注意)

本文目的与要求:

通过实例讲述在Bugzilla系统中如何针对用户应用需求的不同,针对不同产品设置不同的权限。

您需要对Bugzilla有简单的了解和部署经验,并且已经在开始使用Bugzilla。本文中不会针对个别选项、设置进行事无巨细的探讨,也不保证所讲述 的内容涉及到权限设置部分的各个方面。仅以一些实例,为各位Bugzilla用户在各自的应用中起到一些抛砖引玉的作用。

设置不同组权限设置的前提要求:

    首先需要完成Bugzilla里的分组设置。如可根据用户的不同分为"质量"、"前端"、"测试"等不同的用户组。用户可以同属为多个组。组的分类可以和 要提交问题的产品相关,如针对"质量"的问题,会有一个对应的"质量"人员组;也可以和问题不相关,如通常为了管理方便,我会创建一个"部门主管"组(可 查看所有记录)、以及"所有用户"组(通过通配符 .* 匹配所有用户,在使用中可简化一些设置)。以下的几个实例的解决方法,会遵循我在这里的用户组设计。

    如需设置组分类和产品分类相对应,可启用Bugzilla->管理->参数设置->组安全设置 中的makeproductgroups选项。启用此选项后,每创建一个新产品,系统均会自动在用户组中创建一个与此产品对应的用户组。

产品分组权限设置页面:

    无特殊说明,均在Bugzilla->管理->产品管理->产品页面->编辑组访问控制页面中

权限设计需求实例:

  1. 每个用户都可以提交不同产品的Bug
  2. 所有用户均可编辑问题/只有相应组的用户才能编辑相应的问题
  3. 所有用户在提交问题时,均可选择此问题是否针对其它各个部门的人员可见
  4. 产品严格分组,不同的产品组只能查看相应组的产品Bug信息 - 此范例来自 Bugzilla官方手册
  5. 创建一个只读产品(此产品的相关信息只能查看,不能提交和修改)- 此范例来自 Bugzilla官方手册

问题1解决:

    选中"所有用户"组的Entry选项

问题1解决说明:
    
    Entry 选项决定了一个组的用户是否有权限可以针对一个产品提交问题。同时如果有至少一个组选择了Entry这个选项的话,那么其它没有选择的组均无法针对此产品提出问题


问题2解决:

    所有用户均可编辑问题:选中"所有用户"组的editbugs选项
    只有相应组的用户才能编辑相应的问题:依次编辑各个产品,选中相应组的Editbug选项

      
问题2解决说明:

    Editbug 以及 editbugs 两个选项的差别:

  • 当有任何一个组选择了Editbug选项后,其它未选择的组均无法编辑此产品
  • 如果有一个组选择了editbugs以后,该组即可编辑此产品的所有问题


问题3解决

    修改相应其他组的MemberControl、OtherControl权限

    这两个权限各有三个选项

    简单说明,
    一个组的MemberControl指操作中用户属于这个组时,
        Default指可以在界面上选择此组用户是否可查看此产品问题,并且默认此选项选中
        Mandatory指在界面上无法选择此组用户是否可查看此产品问题,但此问题设置为强制与此组用户相关
        Show指可以在界面上选择此组用户是否可查看此产品问题,并且默认此选项不选中
        N/A指与此组完全没有关系,无法访问

    一个组的MemberControl指操作中的用户不属于这个组时的情况,三个选项和上面的相同。


    举个例子

        倘若有一个"主管"用户组,可查看/编辑所有提交的信息(并且此设置不可能由其它用户或相关的Bug提交者所改变),权限可设置为

            主管 Mandatogy Mandatory editbugs

        倘若有一个问题,可能需要"质量"、"前端"组用户查看,但需要提交此问题的用户(所有用户,可以不是这两个组的成员)在提交时进行设置。同时还不需要让"程序"组的用户查看,那么权限可设置为

            质量 Shown Shown
            前端 Shown Shown
            程序 N/A N/A
            所有用户 Entry (或设置为 除"程序"组以外的其他组均可以Entry)

     针对问题三的情况,应该设置成为:

        对其他可能会与此问题相关的用户组,权限设置成为 Shown Shown
        这样在提交问题时,选项里就会出现"是否让一下组查看问题"的选项了。


问题4解决:(此问题可视作问题3里设置权限的例子的一个延续)

产品A里面采用如下设定:
A组: ENTRY, MANDATORY/MANDATORY
产品B:
B组: ENTRY, MANDATORY/MANDATORY
   

问题5解决:(此问题可视作问题3里设置权限的例子的一个延续)

        创建一个用户组,名为"只读"。将需要设置权限的产品设置为
        只读 Entry, N/A N/A, CanEdit

        简单说明
                Entry及CanEdit均为排他设置,只要确保"只读"组没有用户,即可实现无用户可提交和编辑此产品的Bug信息。


Mozilla官方手册中还有不少权限设置的实例,相信在读完以上部分以后,理解Mozilla的说明会更加方便一些。

本文的大多数内容均经过我的实验,但是仅供参考之用,我不能确定文章中的所有设置均正确并适应您的需求,总的来说,Bugzilla的设置,还需要在实践中加以揣摩。

在日后时间宽裕时可能会对此文章进行进一步补充。如对此文章由什么意见或纠正,欢迎留言或直接给我写信,我的邮箱是 我的英文ID@gmail.com

最后需要明确的是"产品"这个概念。我在工作中搭建的Bugzilla系统均不是应用于软件开发领域,而是对流程中的问题进行追踪。"产品"这个在 Bugzilla中的概念,可能在Bugzilla系统根据用户需求进行定制的过程中被其它文字替换。关于针对Bugzilla系统进行定制的更多信息, 欢迎查看这篇文章:OpenParty "有狐",在此次活动中,我进行了一个"Bugzilla系统部署、定制"的演讲,具体的介绍幻灯片可以查看这里《Bugzilla @ Customization》

作者:CNBornbugzilla-cn (Bugzilla中文本地化)项目组成员


主要参考文档

本文中Bugzilla的中文翻译均来自 bugzilla-cn (Bugzilla中文本地化项目)

Bugzilla官方文档中对于产品组权限部分的说明(Bugzilla 3.2) http://www.bugzilla.org/docs/3.2/en/html/products.html#product-group-controls

Bugzilla权限管理讨论,这个是我在中文互联网上发现的少见的关于此问题的帖子,只有2句话,总结得不错 http://topic.csdn.net/t/20061226/23/5258177.html

CMS Made Simple 安全技巧

| 1 Comment
上次说到自己使用建立的CMS Made Simple建立的一个站点被黑了,由于之前没有做好充足的应付这种事件的准备,用了近20个小时才恢复。通过这次事件,自己吸取了沉痛的教训,并且在CMS Made Simple建立的站点的安全性方面,也有了一定的了解;现通过自己的经验以及从CMS Made Simple论坛中学习到的一些东西,整理出几条CMS Made Simple安全技巧:

    1. 足够安全的用户名和密码

          说来好笑,仔细想来,自己站点被黑,密码过于简单其实是直接原因...... 请大家不要使用username:admin password: domainname 这样的密码,设置这样的密码与直接开放后台给公众是一样的。
          尽量不要把管理员的用户名称设置为Admin;六位数的密码被证实安全性已经不像原来那样高了,替换成八位数以上的吧。

    2. 在Config.php中更改Admin目录

          绝大多数由CMS Made Simple建立的网站,在其URL后面加上/admin都会出现未经修改过的CMS Made Simple Login画面,如果存在较严重的漏洞或者遇到好奇心极强的破坏者,岂不是相当于"Welcome to Hack into it!"。我们可以通过修改在config.php里面的

          #Name of the admin directory
          $config['admin_dir'] = 'admin';

          这一项,将admin换成你设想的富有想象力的组合吧,同时也不要忘了把admin/目录改成相应的名字。这样,你至少又给蓄意破坏者增加了一道障碍。

    3. 定期、及时备份数据库

          这一条看似多余但是绝对值得再三强调。天有不测风云,谁又能预知网站将要出什么问题呢?主机停机、非法入侵、文件丢失、数据库损坏、域名无法解析、GFW 都不是不可能发生的事,手头有份备份总要踏实许多。否则,就象曾经幼稚的我那样疯狂使用Google Cache吧......
          备份CMS Made Simple的网站还是非常方便的,只消备份该Installation中使用的那个数据表就可以了,模板、内容、模块设置等信息均包含在里面。CMS Made Simple可选装的模块里也有用于备份数据的模块,可以分别备份不同类型的数据。另外很多数据如模板、模块等也是可以导出成为XML文件的,总的来说, 备份并不麻烦。
          使用软件或后台备份数据库均可,我在使用mysqldumper,很好用,就是在加密上有一点点小问题。最后,不要忘了把数据在本地再备份一份。

    4. 及时将CMS Made Simple更新到最新的版本

          在写这篇文章的时候,CMS Made Simple的最新版本为1.1。在1.0.x的版本阶段,虽然不断有漏洞发现,但是开发团队都以极快的速度推出新版本以填补漏洞。之后的版本据称安全性 有了很大提升,建议大家都更新到最新版本。需要注意的是,在更新版本之前,请备份数据!因为很可能会有一些模块不兼容的问题导致一些功能不能正常工作。
           News模块不工作的情况较为常见,解决方法也很奇怪,在模块管理中将其卸载然后再装上,一次或反复几次就可解决问题。供遇到这样问题的朋友参考。

    5. 文件/目录权限777 or 775 or else 的争论

          在论坛上,有的人认为在安装时需要对
  • tmp/templates_c
  • tmp/cache
  • uploads
  • uploads/images
  • modules
          这几个目录设置777权限以安装提出了质疑。认为这可能带来潜在的安全隐患,并建议大家将其设置为775

          原帖 - Security impacts of chmod 777

          我认为最终kermit给出的答案还是比较合理的,即:安装程序的确需要这几个目录的权限为777,但是出于安全考虑,可将这些目录中的文件权限设置为666,并且把config.php的权限也设置成为666。
          虽然可能这个并不构成问题,但是权限问题的确可能会构成很大的隐患,不可小视。


以上给出了一些CMS Made Simple安全方面简单的一些技巧。文章的内容十分初级,毕竟我也只是个这方面的新手。但是我认为这些问题都不可小视,毕竟这些都是前车之鉴。如果您认为有需要补充或不对的地方,欢迎来信告诉我。


相关阅读:
优秀的轻量级内容管理系统: CMS Made Simple - 一篇关于CMS Made Simple的很好的介绍
《CMS Made Simple的几点技巧》 - 在使用CMS Made Simple架设站点的过程中,可以应用的一些技巧

CMS Made Simple的几点技巧

| No Comments
CMS Made Simple是一个简洁好用的CMS,tarsusa的新网站就是由它驱动的。具体的介绍大家可以参阅以下两篇文章:

优秀的轻量级内容管理系统: CMS Made Simple

简单的cms:cmsmadesimple

以下是我在使用 CMS Made Simple架设站点时,在
CMS Made Simple论坛上看到的一些我认为很实用的小技巧,做一下简单介绍。每一条后面都有相关的链接,供大家参考。


1、 CMS Made Simple Google Sitemaps Generator

为CMS Made Simple站点提供Google 网站管理员工具需要的Sitemaps
只需要把下载的gsitemaps.php复制到CMSMS安装的目录,然后在Google里提交指向gsitemaps.php的url即可

链接:CMSMS Forge - Google Sitemaps Generator


2、根据显示内容的不同定制模板显示

我们可以使用添加标志进行判断的方法,让模板可以根据不同的内容进行变化,以避免在模板库中出现一大堆只是有微小不同的模板

用途:比如网页的大版块和文章显示可以使用同一个模板,但在文章显示的页面上出现"收藏到"以及层次路径指示 (breadcrumbs)
          论坛原贴中举出的应用实例更多,欢迎参考

步骤:编辑需要模板有所变化的页面(这里的例子是显示具体文章的页面),在编辑页面的"选项"选项卡的"可变数据"(即metadata)里面,加入

{assign var='showbreadcrumbs' value='1'}

即定义一个名为showbreadcrumbs,值为1的变量

然后将"可缓存"前面的钩去掉

接着修改模板,加入相应的判断

{if isset($showbreadcrumbs)}
           {breadcrumbs}
<br />
{/if}

这样,所有显示文章的页面上,都有了breadcrumbs,而其它的页面不会受到影响。

这个技巧更多、更复杂的应用,请参考原帖
原文链接:Customizing your template based on the current page


3、一键保存到在线书签

国外的新闻网站常见的,文章底下有一排在线书签的小图标,点击即保存到相应的网站中

步骤:首先创建一个用户自定义标签,粘贴进相应代码(代码很长就不贴了,请参见原贴第一个代码框)
          然后修改需要显示这个的模板,加入这个用户自定义标签(例如如果你定义的是saveto_tools,就写上{saveto_tools})
          修改样式表,将原贴第二个代码框的内容粘贴为一个新的样式表并且绑定到你需要使用的模板上
          将原贴中的那些图标下载下来并且复制到你的网站上(注意要和上面一步样式表中的路径一致,可以自己修改)

这样就可以了。(这个目前还都是外国流行的那些服务,如果针对中文网站使用的话,把中文的那些常用服务修改下加进去比较好)

原贴链接:
News Article Tools (digg, delicious, stumbleupon...) User Defined Tag


4、提升站点速度之更改样式表

查看网站的源代码,找到类似
<link rel="stylesheet" type="text/css" href="http://www.yourdomain.com/stylesheet.php?templateid=23" />
<link rel="stylesheet" type="text/css" media="print" href="http://www.yourdomain.com/stylesheet.php?templateid=23&amp;mediatype=print" />
这样的行,然后把&amp;这个去掉,在浏览器中把这两个文件打开,并且另存为像yoursite-screen.css及yoursite-print.css这样的文件,上传到服务器

然后修改模板,把{stylesheet}字段修改为
<link rel="stylesheet" type="text/css" href="/uploads/yoursite-screen.css" />
<link rel="stylesheet" type="text/css" media="print" href="/uploads/yoursite-print.css" />
注意路径要一致,并且css文件中的图片路径也要一致(我改得很辛苦......)

这样,即把需要stylesheet.php调用的CSS替换成了静态文件,速度大大加快。一般来说,推荐给所有CSS设计已经定型,不需要改动了的网站。

原贴:
  Speed up your site.. lose {stylesheet}


另外,目前版本的CMS Made Simple还不支持多语言站点功能,虽然程序不支持,可是用户们还是实验出了很多的解决方案。比如出现了修改的多语言版
CMS Made Simple Multilingual
这篇帖子 My trick for multilingual pages with regular CMS v1.0.6 提供了一个使用原版程序实现多语言网站的参考,我还没有实验(和上面的第2条技巧实现方法类似),有这个需要的朋友可以试试。

把论坛上的一些小东西简单翻译了一下,感觉CMS Made Simple的中文资料少得可怜(程序的中文化却相当好),贴上这些东西补充一下吧。

这些技巧都不复杂,也都经过我的实验,CMS Made Simple的玩家们可以试试。