Wordpress摘要相关开发

主题开发时又出现使用more标签显示摘要与使用excerpt摘要相关filter出现混淆的问题。

Wordpress主题开发中有两种显示摘要的方法,一种是利用more标签<!--more-->,该方法需要作者在文章适当位置中插入该标签;另一种是正宗的摘要使用函数the_excerpt显示,该方法既可以在文章编辑页面中填入,也会自动生成摘要。

第一种方法可以在调用函数the_content时通过传入参数来定义“阅读更多”链接样式,而与excerpt摘要相关filter完全无关。

第二种方法可以使用多种filter进行“阅读更多”链接定义,使用excerpt_length来定义自动生成摘要的长度(系统默认为55),使用excerpt_more定义自动生成摘要时“阅读更多”链接的样式,使用get_the_excerpt定义手动添加摘要时“阅读更多”链接的样式。

WordPress相关轻博客主题开发经验

轻博客类型的主题已经是现今个人站的设计风尚,不少大型设计博客站点也投入轻博客风格的怀抱,典型的就是Smashing Magzine,其站点的样式充分体现了目前实用类博客的结构设计思路,其结构可归纳为:

导航栏 nav.toplevel

主内容区 div#container > div.sidebar+div.main(fluid)

博客导航区 div#wpsidebar

底部功能区 div#footer

实际上,设计时需要正确理解轻博客的意图,要知晓该风格主题定制性一般不如博客。sidebar功能中小工具功能不可能充分发挥(一般除广告外,只能放置一到两个widget,否则就会拥挤),menu的功能一般也归放到边栏sidebar展示,而很少像以前一样出现在站点中间位置。(网站Smashing Magzine即放到边栏的博客导航区)

本站的最新设计就尽量在经典博客与轻博客风格中寻找一种平衡,但是设计出发点总是信息的有效传达。设计博客的关键在于阅读体验好,在于查找内容方便,所以目前sidebar还是使用了多个widget,menu也仍然放在站点中间。

轻博客主题的另一大特色就是Responsive design,即一次设计必须能够自适应多种阅读终端设备。虽然本人很早就接触过这些内容,但只在本站制作过程中才真正开始使用这些内容。个人感觉自适应设计最关键的技术点在两个地方:一个是字体大小的安排,一个是media query的安排。

字体的大小安排在目前的主题中有两种风格,一种是默认主题twentyeleven中使用的em组织方式,另一种是最新默认主题twentytwelve中使用的rem组织方式。前一种方式的问题主要是使用em为单位需要叠加计算字体大小(可以使用body{font-size:62.5%;}将默认的1em=16px调整为10px,这样计算就方便一些),布局使用的margin或padding也都必须使用百分比或em,故而比较复杂,但是浏览器兼容较好。后一种方法使用了CSS3中加入的rem单位,即相对于根标签html的字体大小,最新默认主题twentytwelve中即使用html{ font-size: 87.5%;}将默认的1rem=16px调整为14px,于是其他所有属性如margin等都以14px=1rem为标准进行编写。但是可惜的是该单位ie8以下都不认识,所以还是必须用px进行兼容,于是还是必须写出body { font-size: 14px; font-size: 1rem;}这样的代码来。

media query的安排必须了解各个阅读终端的屏幕尺寸,下面这个视频对了解苹果系列产品的分辨率及尺寸很有帮助。本站选择了800px与480px两个分界线,来分别对应平版终端(通常需要处理的是竖着拿的情况)与手机终端(横竖都必须处理)。



有关响应式设计与开发可以参考这篇文章

正确理解Wordpress设置API

Wordpress设置API使用起来并不算太方便,很多地方都容易混淆,因此在本人读懂并改写了主题相关的设置类之后,就想把相关容易混淆的地方详细说明一下。

函数register_settingsettings_fields为一组,它们之间使用参数option_group进行关联,另外函数register_setting注册了get_option函数所需要的参数option_name。这两个函数一个用于注册设置信息,一个用于显示设置信息(实际即一组hidden属性的input标签,显示时使用参数option_group)。

函数add_settings_sectionadd_settings_fieldadd_[theme或options]_page为一组,它们之间使用参数menu_slug进行关联,由该参数可知这些函数只与某个特别的page相关,用于注册表单展示信息。使用函数do_settings_sections来渲染展示表单(显示时使用参数menu_slug)。

关于settings的状态栏使用<?php settings_errors(); ?>,该函数即可显示黄色的状态栏。更多状态栏相关开发参考这个链接

 

filter的使用

WordPress开发中action与filter的使用是一个重要的部分,相比action来说filter这个概念更难理解,如果能够完全理解filter,action就根本不是问题。本人也是在开发主题的过程中终于完全理解,于是立即记录分享一下。

filter概念就如名字表示的那样用于过滤输出的内容,相关API很简单,基本就是add_filterapply_filters两个函数。add_filter用于向filter的tag上注册函数,apply_filters则是触发filter的tag从而运行注册在其上的所有函数。

开始本人不理解为何开发需要使用filter时不需要使用apply_filters进行触发反而只在使用add_filter注册函数,如果你也有相同的疑问,那么看下面这个本人碰到的实际例子:

现在需要根据主题设置修改body上class属性的内容,于是可以定义一个函数注册到tag名为body_class的filter上:

function theme_layout_classes( $existing_classes ){
$options = get_theme_options(); //get_theme_options函数可以获得相应主题设置
$current_layout = $options[‘theme_layout’]; //这里得到相应主题使用的布局设置
return array_merge( $existing_classes, $current_layout );//返回增加了设置的class内容
}
add_filter( ‘body_class’, ‘theme_layout_classes’ );//将我们定义的函数注册到tag名为body_class的filter上

这样当调用body_class()函数时(该函数通常在header.php中使用用于输出body的class内容:&lt;body &lt;?php body_class(); ?&gt;&gt;)就会调用我们定义的这个函数,从而将原定输出的class内容加上$current_layout 。

但如果现在需要在显示page时根据page的特殊布局设置覆盖主题的默认布局设置,我们应该如何处理呢?

由于已经把主题设置的class内容加进去了,再使用filter把内容减去就比较困难。实际上解决方法应是将新增的内容进行整体替换,于是我们修改函数theme_layout_classes为:

function theme_layout_classes( $existing_classes ){
$options = get_theme_options(); //get_theme_options函数可以获得相应主题设置
$current_layout = $options[‘theme_layout’]; //这里得到相应主题使用的布局设置
$classes = apply_filters( ‘theme_layout_classes’, $current_layout ); //这里实际我们定义了一个新的filter tag
return array_merge( $existing_classes, $classes );//返回增加了的内容
}
add_filter( ‘body_class’, ‘theme_layout_classes’ );//将我们定义的函数注册到tag名为body_class的filter上

可以看到我们通过apply_filters实际定义了一个新的filter tag,这样我们只要将新函数注册到这个tag上就能够整体替换新增的内容。
于是我们再注册一个函数:

function page_layout_classes( $existing_classes ) {
global $post;
$current_page_layout = esc_attr(get_post_meta($post->ID, ‘page_layout’, true));//获得page的特殊布局设置
if (! empty($current_page_layout) ){ //如果存在特殊设置,则返回这个内容
return $current_page_layout;
}else{
return $existing_classes; //否则还是返回原有内容
}
}
add_filter( ‘theme_layout_classes’, ‘page_layout_classes’ );//将这个函数注册到我们定义的theme_layout_classes上,以实现替换新增内容的功能

这样在调用theme_layout_classes时又会因为apply_filters( 'theme_layout_classes', $current_layout );触发调用page_layout_classes函数,注意page_layout_classes函数第一个参数$existing_classes这里会被赋值为$current_layout,于是就能用page的特殊设置覆盖主题的默认设置。

通过这个例子我们知道产生之前疑问的关键是调用函数body_class()时实际上里面就有调用apply_filters( 'body_class')进行filter的触发(出自get_body_class:wp-includes/post-template.php),当然我们不需要再进行触发,只需要使用add_filter将我们的函数注册即可。

tag与category的使用与自定义标签的设计

WordPress中存在两种类型的分类:一种是tag,另一种是category。这两种分类的区别在于: category通常是有层次的,而tag是平行平等的。

一些著名博客如Smashing Magzine以及Nettut+是如何安排使用tag和category的呢?

最新Smashing Magzine主题是轻博客类型,完全放弃有层次的category,而全部采用平等的tag。

而传统博客类型的Nettut+基本采用category,其URL结构为/articles/javascript或是/tutorials/ 。tag用来标记类型如video或tips,该主题甚至可以结合两者进行查询。

WordPress中可以使用函数register_taxonomy注册自定义标签,区分是category类型还是tag类型的关键就是参数hierarchical。

WordPress中文本地化方法总结与相关问题

终于基本完成本站主题的中文汉化工作,不得不佩服WordPress系统为本地化工作设计的API,尽管不算尽善尽美,但是使用起来还是比较方便的。以及所谓.po和.mo的本地化文件的使用,不知是哪个人发起的主意,确实简化了本地化的工作。废话就不多说,总结下chaozh主题汉化过程中学到的技巧及遇到的相关问题。这些问题都是典型新手会碰到问题,而且尚未完全解决,如果哪位高人看到,可以说出更好的解决方案,本人十分之欢迎!

如果你只想快速了解如何进行WordPress汉化,那么可以参考这篇文章《poEdit制作WordPress主题汉化,插件汉化攻略》,是本人看到最完整清晰的中文本地化攻略。如果仍有问题,请继续耐心看完下面的内容。

补充:(这些补充出自此链接,该文章也大致说了下中文汉化的方法。)

—如果只有.mo文件的话,则需要编译成.po文件处理,可以使用GetText来反编译。

下载地址为:http://www.gnu.org/software/gettext/

—翻译中注意保留变量的原有形态 例如:阅读所有 %s 的文章
—HTML语句中的内容不要翻译
—保存出来的MO文件名是区分大小写的,正确的命名如: zh_CN.mo,可对照language目录其他语言的命名方式。

1.WordPress本地化API

那么首先说说WordPress系统为本地化工作设计的API。在开发过程中可以对需要翻译的部分使用多种函数进行标记,以方便后面的翻译工作,可以使用的函数大致有(),_e(),_x()以及_ex(),还有_n()等。前面的那些比较常用,_n()主要用于区分单复数,所以中文就不太用得着,而且也可以使用其他方法来规避改函数的使用。使用最多的头两个函数接受两个参数,第一个是要显示(翻译)的字符串,第二个是使用的命名空间。这两个函数的区别在于()返回翻译后的文字字符串,而_e()直接把字符串打印出来,而且相信你已经看出_x()和_ex()这对也是类似的区别。命名空间的使用可以用来区分主题,一般主题中function.php文件中有这样的代码来完成本地化文件的读取:

load_theme_textdomain(‘chaozh’, TEMPLATEPATH . ‘/languages’);
$locale = get_locale();
$locale_file = TEMPLATEPATH. “/languages/$locale.php”;
if (is_readable($locale_file))
require_once ($locale_file);

其中,load_theme_textdomain函数就是用来设置命名空间的,经过本人实验如果在这里设置了命名空间”chaozh”,而后面直接写__('Page')而不加上相应的命名空间参数,会导致该信息没有被翻译显示。所以应该写为__('Page','chaozh')来获得翻译内容。

再来说说_x()系列,该函数使用频率其实也不小。该函数接受三个参数,还有一个参数来表明上下文(context),主要用于英文内容相同但希望译文不同的情况。经典例子是管理员菜单中文章目录及页面目录下相同的“Add New”的翻译:如果还使用__()函数会导致同样的英文内容只能采取相同的翻译方式,这样就无法对添加post和page的按钮进行区分,所以要加入上下文环境来帮助翻译。添加文章的信息可以写为_x('Add New','for adding post',‘chaozh’)而添加页面的信息可以写为_x('Add New',‘for adding page’,'chaozh'),这样就可以区分了。

添加post翻译效果添加page翻译效果

参考官方介绍

2.Poedit软件使用遇到的问题

具体用法可以一步步参考前面的文章,这里主要说说需要注意的问题。一个是更新代码后记得点击软件的同步按钮,以把新修改的内容加入到翻译队列中。另一个是改造过程中,本来wp主题文件都是utf-8编码,但是Poedit软件默认的是ansi编码,所以有需要的话要在项目设置上填上,否则会导致文件需要翻译的内容无法同步。

但Poedit软件最大的一个问题是,即使在项目设置的关键字加入_x,该软件还是会无视上下文参数,无法区别显示需要翻译的内容。并且即使把相应地点进行翻译,生成的mo文件最后还是无法显示翻译后的内容。由于本人目前只会使用这个软件来进行汉化工作,所以直接导致目前这个主题里都无法使用_x()函数,目前还不知道如何来解决。

这个问题已经找到一个可行的解决方案,即项目设置的关键字加入时使用_n:1,2;_x:1,2c;_ex:1,2c;这里:1,2说明有两个参数,而c则说明第二个参数是comment类型 具体可以参见这篇文章 于2012-03-31 最新修改!

3.主题开发中碰到的问题

目前还碰到一个更诡异的问题,本人使用theme-options.php文件来生成主题设置界面,其中有段代码:

$controls = array(
array(“name” => (‘Blog Promotion Options’,’chaozh’), “type” => “heading”),
array(‘name’ =>
(‘Display Custom Sharing Widget?’,’chaozh’),
“desc” => __(‘Check here to <b>display</b>.’,’chaozh’)…

但不知何故里面的部分就是无法显示翻译后的信息,默认主题中也有类似的代码:

$layout_options = array(
‘content-sidebar’ => array(
‘value’ => ‘content-sidebar’,
‘label’ => ( ‘Content on left’, ‘twentyeleven’ )…

而显然该主题就没有什么问题。显示方法都是调用echo函数,而且本主题还是有返回原英文信息,这说明()函数还是运行了的,但是为什么会没返回翻译内容呢?这点很是诡异。期待以后能把这个问题解决吧。

4.插件汉化问题 new!

进行插件汉化的过程中,又遇到新的问题,也是无论怎么命名,都无法显示翻译后的内容。相关插件汉化方法,其实与前文所诉一致,就是多了对load_plugin_textdomain函数的使用。而插件汉化的问题基本都是出在这个函数上面,该函数接受多个参数,第一个自然是domain,即命名空间,关键是这个可选的第二个参数。本人汉化的插件名为breadcrumbtrail,但是文件夹无法使用’‘来命名,于是插件文件夹默认名就变为’breadcrumb-trail’,这就导致使用原有的下面的代码无法定位翻译文件:(详情可以参考这篇文章,里面有分析)

load_plugin_textdomain( 'breadcrumb_trail');

因为这默认告诉wp来找名为breadcrumb_trail文件夹下的breadcrumb_trail-zh_CN.mo文件,显然没有这个文件夹,所以必须改为:

load_plugin_textdomain( 'breadcrumb_trail','/wp-content/plugins/breadcrumb-trail/');

即加入指定路径方可成功显示翻译信息。所以这也告诉我们,插件的命名空间命名最好不要使用’_’来进行分隔,或者不要图省事使用第一种代码,而应该加入第二个参数,不给别人本地化工作带来麻烦。

第二个参数可以这样添加:PLUGINDIR . '/' . dirname(plugin_basename (__FILE__)),这样就不需要根据目录名来调整参数代码了。但是第一个参数即插件的命名空间一定要与翻译文件名称相同 于2012-03-18 最新修改!

目前第二个参数已经被废弃了,但是依旧保留,实际上官方推荐使用第三个参数,该参数只要给出.mo文件相对于插件根目录的相对路径即可:dirname(plugin_basename (FILE)) . ‘/languages’。这样设计科学多了,毕竟绝对路径很没必要,谁会没事干瞎改插件根目录 于2012-10-26 最新修改!

本站总访问量