DokuWiki 简明使用教程

什么是WIKI?什么是DokuWiki?

和博客、论坛一样,WIKI 是一种网站的类型,它最大的特点是允许不同的人修改同一份内容,从而使其更加完善。互联网上基于 WIKI 的理念创建的网站中最有名的当数 Wikipedia (即维基百科),尽管它的中文版本在中国无法直接访问,但并不妨碍它成为世界上流量最大的网站之一。如果你没有听说过维基百科,你可以认为它类似于国内的百度百科,不过维基百科比起百度百科内容更加丰富和优质,而且不像百度百科一样商业化。

如果有一台自己的服务器或是虚拟主机,你也可以搭建属于自己的 WIKI,这个过程不需要太多技术知识,因为网上有很多现成的开源程序可用。例如上面提到的维基百科就是采用叫 MediaWiki  的程序搭建的。这里将要介绍的 DokuWiki 就是一款用来构建 WIKI 网站的程序,相比MediaWiki,它更加轻巧和简单(只需PHP环境,无需数据库),适合小型团队和个人网站使用。

WIKI 类网站的适用范围很广,常见可以用作个人或是小型团队的知识库或是用来存放软件的文档等。协同编辑是 WIKI 最重要的特点。

修改页面

当你加入到一个 WIKI 网站(例如公司内部的知识库),除了进行正常的浏览外,最常见的两项活动无非就是修改现有页面新建页面了。

首先介绍如何修改页面。在默认的 DokuWiki 模板下,修改(编辑)页面的入口在页面主要内容区的右侧,是一个铅笔状的图标(见下图)。

Edit Link of DokuWiki

不同的 WIKI 有不同的权限设定,比如有些 WIKI 允许所有人参与编辑,有些 WIKI 则设定了只有部分人(注册用户等)才能编辑——对于这类 WIKI,你需要登陆后才能开始编辑,否则只能浏览。

进入了修改页面后就可以看到编辑区域,现在你可能会发现编辑区域内显示的内容很奇怪,但是不要担心,这些不是什么高深的东西,后面解释了就明白了。现在要知道的是,要修改(或者新建)页面的内容就是这里进行的。编辑完成后,可以点击文本框下方的预览按钮看看效果,满意的话就可以保存。

注:在每次修改后留下修改说明是个好习惯。

新建页面

WIKI 上的每一个页面都不应该是孤立的,不同页面之间应该通过超链接连接起来(孤立的页面即使被创建出来也往往无法被浏览到,因为没有指向它们的超链接)。正因如此,DokuWiki 上并没有单独的新建页面的按钮(当然这个功能可以通过插件来实现)。如果需要为某个主题新建一个页面的话,应该考虑采用『在现有页面上建立一个链接』的方法来完成。

在上一节修改页面中提到,编辑区域内的内容看起来很奇怪,那是因为大多数 WIKI 都会用到自己特有的语法来书写内容。这篇教程中会介绍少量语法,不过当你明白了所谓的语法是什么意思后,你可以自己查阅语法说明来进一步学习。

那么什么语法呢?打个比方:例如你在 WIKI 中加入了如下内容:

Woolandbun 是羊毛和包子系列内容的统称,是一个在想象中构建的虚拟世界。
现在我们想把其中 Woolandbun 这个单词加粗显示要怎么办呢?很简单,只需要在要加粗的内容前后加上两个 * ,那保存以后就能看到对应的加粗效果,就像这样:
加入了加粗语法的句子: **Woolandbun** 是羊毛和包子系列内容的统称,是一个在想象中构建的虚拟世界。

实际的显示效果:
Woolandbun 是羊毛和包子系列内容的统称,是一个在想象中构建的虚拟世界。


际使用中,可以自己查阅语法说明或是使用编辑框上方的快捷工具条(DokuWiki Editor Toolbar)编辑内容。工具条的使用很简单,在上面的例子中,选中要加粗的内容再点击工具条上的加粗按钮(B)就能自动加上星号。

前面说了,要新建一个页面最好的办法是在现有页面上创建一个指向新页面的链接。和加粗文字一样,创建一个链接也有自己的语法,只需要在对应的文字前后加上两个方括号即可。(当然也可以用快捷工具条)

例如,如果要创建一个关于羊毛和包子党的页面,就可以在现有的页面上输入[[羊毛和包子党]]保存后就能看到一个红色的链接(红色代表该链接指向一个没有内容的页面),点击这个红色链接就能进入到一个空白页面,然后就可以按修改页面的方法输入内容,保存后新的页面就创建完成了。

在实际的使用中,我们建议采用[[woolandbun|羊毛和包子党]]这样的形式来创建页面的链接。为什么呢?简单地讲就是给创建的页面起一个英文名字。两种方式显示的链接文字都是羊毛和包子党,区别在于页面的网址不同,例如前一种方式生成的网址可能会是 http://wiki.lichifeng.com/羊毛和包子党/ 而后一种方式生成的网址则会是 http://wiki.lichifeng.com/woolandbun/ 显然英文的网址更利于 SEO。

关于创建各种链接更详细的说明可以查阅链接的语法说明

删除页面

要删除页面只需在编辑框内把所有内容清空后保存即可。

使用标题生成目录

好的内容首先要有好的结构。如果你浏览过维基百科或是国内的一些百科网站,不难发现绝大部分页面都会有一个层次清晰的目录,就如下图中红框所示:

DokuWiki ToC Sample

这个目录是如何生成的呢?显然不是作者手工输入的,在大部分 WIKI 中这样的目录都可以自动生成(这种目录一般称为 TOC,如果想要搜索相关插件,可以用 TOC 作为关键词)。

那 WIKI 又是根据什么来生成的内容的目录呢?它怎么知道哪些是大标题,哪些是小标题呢?答案上面其实已经提到——通过WIKI 的语法来指定。

例如我们有如下内容:

Wiki 是一种在网络上开放且可供多人协同创作的超文本系统,由沃德·坎宁安于1995年首先开发。沃德·坎宁安将 wiki 定义为“一种允许一群用户利用简单的描述来创建和连接一组网页的社会计算系统”。

词源

wiki 源自夏威夷语的 “WikiWiki”,本是“快点快点”之意。wiki的中文翻译有维客、围纪、围记、快纪、共笔或维基等等,其中“维基”一词是中文维基百科人特别为维基百科而创,属于维基媒体的专用术语。

历史

Wiki 软件是由软件设计模式社区发展出来,用来书写与讨论模式语言。沃德·坎宁安于1995年3月25日成立了第一个 Wiki 网站:WikiWikiWeb,用来补充他自己经营的软件设计模式网站。他发明了 Wiki 这个名字以及相关概念,并且实现了第一个 Wiki 引擎。坎宁安说自己是根据檀香山的 Weekee Weekee (快点快点)公车取名的。这是他到檀香山学会的第一个夏威夷语。

特征

奥德·坎宁安和波·路夫(Bo Leuf)在《The Wiki Way: Quick Collaboration on the Web》一书中描述了 Wiki 概念的几个本质特征:
Wiki 允许任何用户在 Wiki 网站内剪辑任何页面或新建页面,不需要任何额外的附加组件,只需通过普通的网页浏览器即可。


显然文中的“词源”、“历史”、“特征”适合作为目录内的标题。那我们只需在需要作为标题的内容前后加上一定数量的英文等号和空格即可,如果一篇内容含有超过三个标题(不同的 WIKI 设定不同,有些可能不是以三个为阀值),目录就会自动生成。

上面的例子就可以改为:

Wiki是一种在网络上开放且可供多人协同创作的超文本系统,由沃德·坎宁安于1995年首先开发。沃德·坎宁安将wiki定义为“一种允许一群用户利用简单的描述来创建和连接一组网页的社会计算系统”。

==== 词源 ====

... ...

==== 历史 ====

... ...

==== 特征 ====

... ...


目录可以有很多层,不同层次的目录用不同数量的英文等号标记。更详细的语法说明可以查看这里:DokuWiki语法

插入图片

插入图片有两种方式,一种是直接上传,另一种是引用其它网站的图片。一般来说,除非来源很可靠,最好不要引用来自于其它网站的图片,有很大可能对方关站或者其它原因导致图片失效不能正常显示。

图片插入流程不废话,直接录了一个简单的录像:(动画尺寸略大,约1M,请点击观看)

dokuwiki insert image

在Ubuntu 15.10下配置LEMP环境(Linux + Nginx + MySQL+ PHP7.0)

0 准备工作

这里假设已经新建了一个VPS并能够通过SSH连接上服务器。系统方面我采用了Ubuntu 15.10

首先安装一些常用的工具,我习惯用 VIM,所以还顺便加载了常用的一套 VIM 配置文件。当然只是用来配置网站的运行环境的话nano就足够了。

aptitude install git vim python-pip
git clone git://github.com/amix/vimrc.git ~/.vim_runtime
sh ~/.vim_runtime/install_basic_vimrc.sh

1 基本的系统设置

设定主机名称(hostname)

$ hostnamectl set-hostname hostname

把上条命令中的hostname 替换为主机名字

1.1 更新hosts

更改/etc/hosts

127.0.0.1   localhost.localdomain localhost
12.34.56.78 hostname

这里的hostname 需要改成前面设定的对应值。

1.2 设定时区

dpkg-reconfigure tzdata

设定完成后可以输入date 命令再次确认是否设置成功。

1.3 配置自动更新(unattended-upgrades)

一般情况下系统已经配置了自动更新,可以配置为定期升级所有软件包或是仅升级安全相关的内容,如果不确定是否已经存在于系统,可以尝试安装一下:

apt-get install unattended-upgrades

关于自动更新的详细内容,请参考:https://help.ubuntu.com/lts/serverguide/automatic-updates.html

2 新增用户

到目前为止都还是用root账号在进行操作,这是不安全的习惯。比较推荐的的系统管理方式是通过非 root 账号进行管理并设置禁止使用密码登陆 root 账号(可以配置为证书登陆)。

$ adduser example_user
$ adduser example_user sudo

3 配置防火墙(ufw)

Linux的内核包括了一个叫netfilter的子系统用来管理进行服务器的网络流量,但是它非常底层,没有用户界面,所以就有了经常听见的iptables。iptables可以认为是对netfilter的一个包装。

但是通过iptables配置过服务器的防火墙比较繁琐,所以又有了ufw。ufw可以比较方便地生成iptables的规则,可以认为是对iptables的进一步包装。关于ufw的进一步信息,可以到这里查看:https://help.ubuntu.com/community/UFW

默认情况下,Ubuntu中的ufw默认是关闭的,可以通过以下命令查看ufw的状态:(接下来默认已经不再直接用root账户登陆,所以命令前会加上sudo)

sudo ufw status verbose

在制定具体的防火墙规则前,先设定好默认的防火墙规则:

sudo ufw default deny incoming
sudo ufw default allow outgoing

以上两条命令的意思从字面上就可以理解——拒绝所有进站的流量,允许所有出站的流量。如果之前有过用iptables配置防火墙的经验就不难发现ufw的方便之处——不用输入包括IP地址在内的难以理解的规则条目,只要通过简单易懂的英文单词就可以操作防火墙(当然也可以使用IP和端口的组合,只不过还是比iptables来得方便)。另外需要讲一下的是:默认情况下ufw会允许ping(ICMP)请求

接下来可以制定一些常用的防火墙规则了。如果只是用来做小型网站的服务器,其实只要开放ssh和Web(80)端口即可(FTP不是很必要,通过SFTP传输文件即可),如果有计划上SSL证书,HTTPS需要的端口也可以开放。在ufw的命令中可以直接使用端口号和IP地址,不过一些常见的任务也可以直接输入英文单词(这才是用ufw的意义所在):

sudo ufw allow ssh
sudo ufw allow www
sudo ufw allow https

到目前为止ufw设定的防火墙规则还没有生效,因为ufw默认是被关闭的,所以还需要将它启用使前面输入的规则生效:

sudo ufw enable

4 配置WEB服务器

这里配置的WEB服务器环境是LEMP,其中PHP采用7.0版本。

目前为止(2016.3.4),Ubuntu默认的软件仓库中还没有包含7.0版本的PHP,如果要体验PHP7.0一般来说需要自己编译。不过也有相对省事的办法,那就是通过PPA安装。PPA是Personal Package Archive的缩写,顾名思义,是由个人分发的软件包,理论上安全性是有一定问题的。不过这里用到的这个PPA目前来说是被广泛使用和认可的,如果只是用来做个人网站的服务器用不用太过担心。

4.1 添加需要的PPA

以下的命令会将安装PHP7.0所需的PHP添加到系统中然后顺便升级一下系统内的软件包:

sudo apt-get install software-properties-common python-software-properties
sudo add-apt-repository ppa:ondrej/php
sudo apt-get update && sudo apt-get upgrade

因为这个PPA作者的名字中含有一些特殊字符,如果系统的字符集不是UTF-8的话可能会遇到一点问题,解决方案很简单,详见:https://github.com/oerdnj/deb.sury.org/issues/56

另外该PPA的官方网页是:https://launchpad.net/~ondrej/+archive/ubuntu/php

4.2 安装PHP7.0

运行以下命令安装php7.0:

sudo apt-get install -y php7.0 php7.0-fpm

这个PPA只包括了Ubuntu 14.04, 15.10, 16.04三个版本的Package,所以如果你安装的不是这三个版本之一,会遇到找不到软件包的提示。

4.3 安装Nginx和MySQL

sudo aptitude install nginx
sudo aptitude install mysql-server

安装过程中会需要你输入MySQL的管理员账号和密码,按提示操作即可。

4.4 安装常用的PHP模块

sudo aptitude install php7.0-mysql php7.0-curl php7.0-json php7.0-gd php7.0-mcrypt php7.0-opcache php7.0-xmlrpc php7.0-intl php7.0-xml

4.5 进行必要的配置

/etc/php/7.0/fpm/php.ini中将选项cgi.fix_pathinfo的值更改为0:

cgi.fix_pathinfo=0

/etc/php/7.0/fpm/pool.d/www.conf中将修改以下两行:

; listen = /run/php/php7.0-fpm.sock
listen = 127.0.0.1:9000

修改PHP上传文件大小限制:

/etc/php/7.0/fpm/php.ini中修改如下两项设置(把100M改成对应的数字):

upload_max_filesize = 100M
post_max_size = 100M

在Nginx的配置文件/etc/nginx/nginx.conf中,修改(或增加)以下一行:

client_max_body_size 100m;

重启PHP-FPM和Nginx服务让配置生效:

sudo service nginx restart
sudo service php7.0-fpm restart

到这里为止,网站的运行环境基本搭建完成。在这个基础上,如果需要搭建WordPress之类的程序只要在Nginx中设置好对应的虚拟主机即可。如果不希望通过MySQL命令行来直接操作数据库,可以安装phpMyAdmin。

另附:WordPress推荐的Nginx设置:https://codex.wordpress.org/Nginx

[WordPress 主题] Goule 文档 | Documentation for Goule

这里是 WordPress 主题 Goule 的官方页面,目前的最新版本是 1.0.3,下载地址:GitHub

主题介绍

Goule 是一个基于 Bootstrap 开发的单栏响应式 WordPress 主题,界面简单干净,可以同时兼容手机和电脑屏幕,定位是小型个人博客主题。目前已提交到官方的主题目录,尚在审核中,暂时可以在 GitHub 下载试用。

Goule是一个免费的主题,你可以随意使用它。

界面截图

Goule 1.0.2 screenshot

下载地址

安装使用

  1. 下载包含主题文件的压缩包(下载地址见上一节)
  2. 将压缩包的内容解压并上传到WordPress根目录下的wp-content/themes/ 文件夹下
  3. 将解压或上传后的主题目录名称更改为goule
  4. 在WordPress后台激活使用

使用说明

  1. 主题可以自定义导航菜单(位于博客名称之下),可以到后台导航 -> 菜单 进行相关设置
  2. 导航菜单使用了wp-bootstrap-navwalker,提供了一些额外功能。例如:在导航菜单项中插入 Glyphicons 图标。具体可以参考 wp-bootstrap-navwalker的说明。可用的 Glyphicons 可以在 Bootstrap 的网站上找到
  3. 网站的档案页面可以同时显示TAG、分类、日期、附件的列表,如果需要使用可以新建一个页面,选择使用档案(Archives) 模板即可
  4. 主题的定位是小型博客,注册登陆这样的功能不是特别需要(小型博客很少有固定用户),所以登陆和登出链接设置在页面最下方,比较隐蔽(考虑到一般只有管理员会用到)
  5. 管理员登陆后如果需要直接在文章页面跳转到编辑页面,点击顶部 Admin bar 上的编辑文章即可(多数主题在登陆后会有文章旁边放置一个“编辑”按钮),如果你禁用了 Admin bar,可能会有点不方便

Here is the official website of Goule, a WordPress theme developed by me, its lastest version is 1.0.3.

The latest version can be found at GitHub(click to download page) .

Introduction

Goule is a free responsive single-column WordPress theme with Bootstrap bundled. It's simple, clean and compatible with mobile devices and desktop screens. Goule was designed for small blogs.

I have submitted Goule to WordPress official theme repository, but is still under reviewing. You may download a zip package on GitHub for a try.

Screenshot

Goule 1.0.2 screenshot

Download

Installation

  1. Download the zip package(See Dowload section above)
  2. Follow the official guidance for add a new theme

How to Use

  1. To configure the navigation menu(located under the blog title), go to Appearance > Menus
  2. The navigation menus makes use of wp-bootstrap-navwalker for some wonderful functions. For example: adding Glyphicons icon bundled in Bootstrap to a menu item. More detail can be found here. Available Glyphicons can be found here. A readme.txt, located at directory root of this theme, also contains details about how to use this
  3. An useful archive page template is delivered with Goule, which is capable of listing TAGs, categoies, date archives, attachment archives on a single page. To use this, create a new page and choose the template Archives
  4. This theme is aimed for small blog using, that is why login/logout button is put at bottoms of pages rendered with small-sized text. Also for the same reason, no Edit button will be found at post/page even if you are logged in as an administrator, because users are expected to use Edit Page/Edit Post link on the Admin bar which will be shown after logged in. I know this will cause some inconvenience to those who have disabled the Admin bar. I'm sorry for that. :(

将QQ同步助手导出的通讯录导入iCloud的方法

QQ同步助手导出的vCard格式的通讯录直接导入网页版的iCloud会出错

解决方案如下:

  • 从QQ同步助手导出vCard格式的通讯录
  • 导入GMAIL的通讯录
  • 在GMAIL中合并重复联系人
  • 从GMAIL中导出vCard格式的通讯录
  • 导入iCloud

对Queryset进行查找、过滤时使用动态的字段名

对Queryset进行查找和过滤是Django中最常见的操作之一,不过一般情况下是对已经确定的字段进行查找或是过滤,例如:

Entry.objects.get(id=123)
# 或是更复杂一点,用到lookup type
Entry.objects.get(headline__contains='Lennon')
在这样的查询中,idheadline都是已经确定的字段。

如果想要动态地指字被查询的字段,可以像这样做:

kwargs = {
    '{0}__{1}'.format('name', 'startswith'): 'A',
    '{0}__{1}'.format('name', 'endswith'): 'Z'
}
Person.objects.filter(**kwargs)
“这在Python中是非常普通和常用的技巧。”1