开源新手的生存技能

曾经是个什么也不会的菜鸟,一头闯入开源世界。虽然现在依然与开源大佬差距很大,但总算是在这个神奇的世界生存下来了。

在开源社区混迹,有一些必备技能还是要学习的。

计算机知识

开源技术往往和计算机有关系,即便做的是硬件,也需要和别人分享,这就用到计算机和网络。

给你的计算机装一个GNU/Linux吧,这除了让你看起来更酷,还会让你领略开源的精髓。从很大程度上来说,开源即源于Linux。它的很多理论和技术,如此广泛的应用于开源世界。

网络技术

知道如何上网,并掌握常人不会涉及的网络技术,是很有用的。你需要让自己的设备总是能连接互联网。拥有一个强大的浏览器和精选的神奇插件,可以替你自动刷论坛。学着用FTP吧,这种古老的方式,现在看起来依然简单有效。熟练地收发邮件,与外国朋友友好交流。玩转邮件列表,乐在其中。熟悉IRC帮助你快速和其他人沟通想法,虽然它简单得好简陋。

必要时,你会自己搭建FTP或者网站,那些服务器知识其实并不复杂。

CVS,SVN和GIT

这三个工具是联系全世界开源人士的重要桥梁。有了它们,所有人可以更简单地控制大量的代码版本。如果你要为某个开源软件贡献代码,编写文档,甚至翻译,都肯定会需要它们。

命令行

不论是在Windows还是Linux操作系统中,会使用命令行都是从普通用户晋升高级用户的标志。虽然很多功能已经图形化,但仍有一些重要的部分,需要用命令行实现——比如你要关掉X图形服务,并让其重新启动。使用命令行有时会比图形界面更有效率,比如你要将文件名中含有“linux”的文件批量修改为“GNU/Linux”,只需要用一行命令就可以做到。最后,对着黑白的终端敲命令行总是让男孩子看起来更酷。

在命令行里进行简单文件操作,编辑文本文件,运行命令行程序,编写Shell脚本,可以帮你体会一种古典的思维方式。你可以将所有命令设定好,等它们执行,然后去喝杯茶。

Wiki

这里说的主要是MediaWiki,也包含其衍生物。Wiki是一个重要的在线协作平台。大量开源项目使用它来管理重要的文档、帮助。使用强大的Wiki获取内容,并将自己所知发布,与世界各地的人无缝协作。MediaWiki的下一个版本将拥有可视化编辑器,但晓得Wiki语法还是很有帮助的。如果你已经了解HTML,那么Wiki语法就非常简单了。

Bugzilla

如果你遇到一个Bug,可能会非常沮丧。但不要只是这样,花一些时间汇报Bug能帮助开发者修正错误,让更多用户受益。第一次使用Bugzilla可能会有些头晕:那些乱七八糟的Bug状态和标签是什么意思?很遗憾并不是所有错误追踪系统都一样,有些差异很大。不过通常你只需要花几分钟就会了解它,并且下一次就可以非常熟练。不同的错误追踪系统,原理和框架却是类似。一次学习,就能解决以后可能遇到的麻烦。

工业设计系教学建议

现状

工业设计系目前有两个专业:工业设计与艺术设计。两个专业的主要课程重合,又有些不同。虽然是针对工业设计专业所提,这些建议大部分也适合于艺术设计。

2010级工业设计主要来自第一批科技与创意设计试验班。从第一年接受了部分美术和设计基础课程,但实际上并没有很牢固。这些学生大多数都没有过美术学习经历,只能依样画葫芦,完成作业。而美术基础却是需要时间来反复磨砺的。而由于美术基础课会占用大量时间,科学技术类的课程,如数学、物理,则被大大简化。这对后续的教学产生了深刻影响。
在选择专业的过程当中,又有不少学生从两个工学试验班甚至医学、农学转过来。这部分同学是没有美术基础的。他们往往是在大二、大三甚至大四修读本该大一完成的美术基础课。这就导致整个工业设计专业的培养方案是被颠倒执行的。虽然从结果来看,学生修读完了所有学科的课程,但效果却与制定培养方案的初衷向违背。

艺术设计的学生原就是艺术生,美术积淀比较多,而在一些技术方面非常薄弱。原本工业设计与艺术设计在一起上课交流的目的即是优势互补。但实际上互补并不充分,尤其是对工业设计专业的同学,艺术和科技的能力都不突出。而与其他专业的交流,尤其是与计算机学院其他专业的交流,亦非常有限。

近年来,工业设计专业学生的发展有了更多元化的趋势。做产品设计的人少了,而做信息服务、软件交互设计、网页设计等新方向的人多了。原有的培养方案实际上是一个选择性很小的套餐,而不是像计算机科学与技术那样的模块化培养方案——就像自选餐。可选择不多的原因是工业设计系的课程非常少,而进一步的原因是教师数量太少,再进一步的原因是年轻教师的待遇太差。

工业设计的教师队伍人数不多。很多课程我们需要依赖外聘的老师,来自中国美院或者城市学院。仅有的教师也因为科研项目或者自己的业务经常出差,课程教学工作无法做到与学生充分交流,甚至有课程停上甚至研究生代讲的问题。这也导致了课程计划没能有效开展,甚至一些课程根本没有教学计划。没有执行课程计划,导致效率低下,不能保证教学目标达成,最终的损失还是要学生来承担。

工业设计的教育需要额外的硬件设施,就像计算机专业需要机房和电脑一样。各校办工业设计系,必备的有画室、摄影室、模型工坊。而这些工业设计系目前都没有,我们仅有几间刚刚够用的教室,(每个年级一间)而且硬件设施非常匮乏,投影仪坏了一年多没有修。设施缺乏导致很多课程,如立体造型、色彩构成,都无法开展。学生有一些好的想法,比如一些立体的造型,或者想把设计做成模型测试效果,都是非常困难的。艺术设计的学生学费比普通学生高一倍,但却没有得到相称的教学资源。

学院的四个专业中,其它三个基本上都是计算机类衍生的,管理和评价方法相似。但工业设计系的情况几乎完全不同,我们很少有计算机课,我们大部分课程属于课堂交流、工作坊形式的。而学院在统计课程评价的时候,经常忽略这一点。比如课程调查问卷,很多项是不符合工业设计特点的。像教学所使用的语言、教材的技术权威性等等。由于只有工业设计系在紫金港校区,学院的很多工作会忽略工业设计系,比如年级大会的主题基本都是与计算机和软件工程专业相关的,少有提及工业设计。

当前教学工作中,大量政治化和商业化因素在入侵。比如市政府办的创意杭州与我们的一些课程直接捆绑。还有一些企业的设计竞赛或活动,直接植入到课程里面。还有老师会将自己与某些公司的业务搬到课堂里面来,作为课程的课题作业。这样做虽然增加了学生实践的机会,但也有弊端。课程是有其专门的目的和安排的。很多精品课程的内容、课题选择、课时安排、教学目标,都是经过仔细推敲和严格控制的。而这些商业和政治活动的引入,将整个秩序都打破了,导致课程碎片化,教学目标偏离。

然后教学工作的监督评价情况。浙江大学对本科生教学工作的规定是非常严格的,但这些并没有在工业设计系的教学工作中充分落实。研究生代讲课、课程取消、到课率低等等情况才会普遍发生。如果学院在查课方面做得更到位,老师自然会更认真地对待教学工作。反之,老师可能会更愿意去忙自己的事情,放任教学工作的荒废。

教学工作组织不力的一大后果是学生的自由化。很多工业设计专业和艺术设计专业的学生感觉课程可上可不上,内容也无法吸引他们,甚至令他们很失望。因此他们会选择开辟自己的道路,由自己决定要做什么事。我们有的同学经常离开学校好几个月,音讯全无,考试不能通过只能休学;还有人在宿舍整日做自己的绘画创作,课程很少参加;还有不少沉迷游戏,无法自拔……而上游对下游的情况非常不了解,缺少沟通是非常可怕的。

培养方案建议

模块化

针对信息媒体设计、设计管理、传统产品设计等设置可选模块。学生只要完成一个模块即可结业,而不必去修读那些自己不感兴趣的课程。

去同质化

一些课程虽然名称不同,但却趋于同质化,比如计算机辅助设计基础,计算机辅助工业设计都是在讲CAD类软件使用。对这些课程进行合并精简,能够提高效率。

调整顺序

课程的先后关系存在一些问题。比如设计思维与表达课程,需要对设计已有比较多的认识才好开展,同时也需要CAD建模能力完成作业。而计算机辅助工业设计和工业设计史却都在这门课之后。

内容调整

建议课程中的电路原理、数字电路课程过于专业化,而缺少对设计整合的可用性,建议已其他课程替代,或者针对工业设计特点推出一门定制化课程。

软件工程课虽然是专业选修,但不在紫金港校区开课,10级几乎没有同学修读。建议在紫金港对工业设计开班,或者从培养方案中取消。

跨专业合作课程

与某个专业同学合上的课程。比如与数字媒体系的同学同上数字媒体设计,不同专业的同学结成一组,通过工作坊的形式合作。跨专业的合作有助于工业设计系的同学进行更深层次的互补,弥补当前工业设计和艺术设计内部交流的不足。

教学工作建议

增加教师数量

教师数量少的弊病如下:
1. 课程数量少,缺乏选择,很多应该跟上时代的课程找不到老师来开
2. 由于课程难以安排,一些老师不得不担任自己不熟悉的课程,课程无法充分开展
3. 部分课程只能启用外聘教师,而外聘教师对浙大工业设计可能并不了解

而增加教师数量必须提高年轻教师的待遇,尊重本科生教学工作取得的成绩。

课程监督有效化

目前学院的课程情况调查仅限于教务网的评价与纸质的调查问卷,而缺少实地的课上情况调查。

当前的现状是,在线点评和问卷并不能获得真实的情况,工业设计的教学内容和形式存在特殊性。到课率、老师的考勤都没有得到落实。

建议由专人进行各个课程的调查反馈工作。一方面监督课程的开展情况,一方面与学生互动沟通课程情况。

落实课程计划

每个课程都应当具有一个可执行的课程计划,不然无法保证课程目标的有效达成。这一点应当纳入到课程评价体系当中去。

课程计划的落实情况也应当受到监督反馈。教学计划更改必须有合理原因,教学计划无法完成也应作出解释。

项目与课程分开

像创意杭州这样的项目虽然是锻炼的好机会,但也容易把课程搞得一团乱。应该尽量将两件事分开,在课程中做创意杭州的项目并不明智。一些企业的商业项目则更应当让学生在课余时间自愿参与,系里可以组织相应的工作坊,避免干扰到教学工作的正常展开。

一切应为课程服务,而非课程为项目服务。

教学资源建议

增加必要教室

包括:
1. 模型坊,配备操作台和切割打磨等工具
2. 摄影室,摄像器材和幕布、反光板、灯箱
3. 画室,绘画素材和模型,可与其他专业共用
4. 专业教室,每个班应当有一个教室,三个年级六个班,应该有六个专业教室,但现在只有三个,50个人挤在同一个教室

专业教室优化

包括:
1. 改善网络状况

这些情况曾向学校相关部门反映过,但都不了了之。

自行车测速器

今天做了一个为自行车测速的传感器。原理很明了:在自行车轮圈上均布贴上黑色贴条,而轮圈接近白色,转动时灰度传感器就会采集到黑白交替的频率,以此确定速度。

灰度传感器模块由光电对射管和放大器电路组成,能以某一基准分辨反射灰度是偏黑还是偏白。这个基准可以通过调节电位器来改变。灰度传感器采集的是反射灰度,而非颜色实际的灰度,反射面的角度和距离都会产生影响。即使是黑色,在足够近的情况下也能反射足够多红外线。因此在使用过程中要调节。

采集频率是简单的,但如何采集到可靠稳定的数据就有不少麻烦。于是我们采用了连续采样拟合的办法,尽量避免速度的异常波动。

在控制指示灯的过程中,我们的电路装在自行车上,不易于连接电脑调试。我们用蓝牙模块接在Arduino板上,通过手机接收,解决了这个麻烦。

Arduino与Processing的串口通信

在网络上普遍存在的Arduino与Processing互动的例子,都具有一个很简单的构造:Arduino上用Serial.print()发送,在Processing中用Serial.readString()读取,或者反过来。然而实际应用过程中大家就会发现这个简单的逻辑模型会发生莫名其妙的错误。最显著的是有时候会收到空值,即使用Serial.available()检测,也会有时收到间断的字符串或者多个字符串混在一起了。

下面是一个经典的Processing与Arduino通信实例:

//Processing Code
import processing.serial.*;

Serial myPort;

void setup(){
  myPort = new Serial(this,"/dev/ttyACM0", 115200); //Set Serial Port

}

void draw(){
  if(myPort.available()>0){
    String message = myPort.readString();
    println(message);
  }
}
//Arduino code
int data=12345; 
void setup()
{
  Serial.begin(115200);//rate
}
void loop()
{
  Serial.print(data); //send data
  delay(1000);
}

然后我们期待着每次获取“12345”并显示在屏幕上,但事与愿违,我们得到的情况是这样的:

12345
123
45
12345
12345

输出时的中断是怎样产生的呢?要探究这个问题的根源,需要重新审视串口通信的原理。

串口通讯就像一趟公共汽车,每个字节是一个在等车的人。他来到车站(发送数据),车还没有来,所以新来的人就一直等待(缓存)。当公共汽车来了的时候,将这些人一次接走(读取数据),当然车也是有容量的,只能载一定数量的人(缓存大小)。现在有一个旅行团(字符串/字符数组),一部分人走在前面刚刚赶上了车(被读取),而另一部分人没赶上,只能等待下一班车(下一次读取)。另一种情况是,两个旅行团都在车站等车,被同一班车接走了。这就是为什么我们读取的时候字符串会断成两节,或者并起来。

核心原因是:串口流通的数据都是bytes而没有字符串概念,所有发送数据都会按一个byte一个byte缓存,不论是否是连续字符串;而读取时会取走所有缓存bytes,不论它们是否是一个、半个还是多个字符串。

Arduino和Processing的数据收发速度是不一样的。如果用Arduino延时较长时间,Processing可能读取一个字符串或字符串的一部分。如果Arduino延时较短,Processing可能读取多个字符串,但不一定完整。在读取字符串的时候,无法确定上一个字符串是否被读取了,当前字符串是否缓存完毕,因为字符串都已经切成了bytes,连成一串。这个问题是串口通信本身造成的,一定会出现。

一种解决方法是,通过在接收端缓存数据来解决这个问题。为传输数据设置一个结束标记,如’\n’(换行符),就能在接收到的数据流中识别到一个字符串的结尾。当未遇到结束标记,就一直将串口数据保存在一个buffer变量中,继续接收。

Processing的SerialEvent事件类型就提供了这种方式,使用bufferUntil(ch)可以在遇到某个指定字符时才完成缓存。

程序实例:

//Processing Code
import processing.serial.*;

Serial myPort;

void setup(){
  myPort = new Serial(this,"/dev/ttyACM0", 115200);  //in fact, any rate is ok...
  myPort.bufferUntil('\n');  //buffer until meet '\n', then call the event listener
}

void draw(){
  
}

//listen to the event. when buffer filled, run this method
void serialEvent(Serial p) {
  String inString = p.readString();
  print(inString);
}

//then the buffer will reveive all the bytes
//Arduino Code
int data=12345; 
void setup()
{
  Serial.begin(115200);//rate
}
void loop()
{
  Serial.println(data); //send data, end up with '\n'
  delay(1000);
}

当然,这种方法也可以用在普通的串口通信中,不必使用SerialEvent。接收的数据不直接使用,而是作为缓存。若未遇到结束标记,就继续读取下一次。当遇到结束标记,即完成缓存。

程序实例:

//Processing Code
import processing.serial.*;

String message;
String temp;
Serial myPort;

void setup(){
  myPort = new Serial(this,"/dev/ttyACM0", 115200); //Set Serial Port
}

void draw(){
  if(myPort.available()>0){
    temp = myPort.readString(); //temp for read bytes
    for(int i = 0; i < temp.length(); i++){
      //if meet the end mark
      if(temp.charAt(i) == '\n'){
        println(message);
        message = "";  //clean string
      }
      else
        message += temp.charAt(i);  //store byte
    }
  }
}
//Arduino Code
int data=12345; 
void setup()
{
  Serial.begin(115200);//rate
}
void loop()
{
  Serial.println(data); //send data, end up with '\n'
  delay(1000);
}

遥控变色灯

课程作业总是没完没了。有时候不得不日复一日地做同样的事情,虽然明明知道不久就会全忘掉。

早晨起来就开始琢磨这次信息产品课要做点什么。淘宝上买的蓝牙模块还没有送到,电脑无线互动做不了。而且第一周是基本练习,包括数字输入输出,模拟输入输出,串口上载和下载,开关。原材料也很少,电阻,LED,一个全彩LED,遥控器,还有光敏二极管,电位器,开关,小键盘什么的。最后选择了全彩LED和红外遥控器。全彩LED我是第一次用,红外遥控看起来很酷。他们拼起来便是一个遥控变色灯。

原理设想比较简单,通过红外遥控输入控制信号,使R,G,B值增减,单片机控制三路PWM输出的占空比,从而达到变幻颜色的目的。电路也很快搭好了,只接了两个元件:全彩LED,红外接收器。全彩LED使用了9,10,11三个PWM端口,而红外接收器接在13端口。
遥控彩灯原理图示意
Arduino有现成的红外接收库。一开始就非常顺利地接收了红外遥控的信号,并记录下了每个键所对应的值,这是通过串口发送电脑回来的。很特别的是,当一直按下一个键时,后续会重复返回FFFFFFFF。然后根据按键控制红灯的亮度,并设计成若一直按下,则会重复动作,这样就不必按很多次按钮了。

当我们如法炮制,添加了绿灯,一切正常,添加了蓝灯,却无法工作。按下蓝灯控制键,程序便会中断。这是为什么呢?我们开始一直以为是遥控的原因,更换了遥控上的其他键来控制,情况是一样的。后来我们又检查程序,将可能的错误修正。但依旧是红绿灯正常,而蓝灯不能使用。三个灯应该是对等的,如果其他两个没有问题,说明程序是可行的。既然该换了按键也没有用,说明遥控这部分也没有问题。我们将蓝绿调换,发现蓝色可以正常工作,说明全彩LED正常。所以最终有问题的是电路板硬件或者连接。蓝灯接入的11端口可能存在问题,便将其该换到6号端口,如此就解决了问题。

AVR单片机的6路PWM是有差异的。Arduino将其同质化处理,虽然简化了认知过程,但导致很多问题无法解释。机器人协会曾经也讨论过是否要引进Arduino,但后来还是否定了这个计划。因为Arduino的思维方式虽然在早期能够快速入门,但却导致在进阶的过程中处处遭遇困难。以后再去认识硬件细节的设计,摒弃原有的理解,是非常困难的。

IMG_0054

IMG_0055

IMG_0056

#include "IRremote.h"

int RECV_PIN = 13;

int red = 0;
int blue = 0;
int green = 0;

int last = 0;
int now = 0;
 
IRrecv irrecv(RECV_PIN);
 
decode_results results;
 
void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn();
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(6, OUTPUT);
}
 
void loop() {
  
  if (irrecv.decode(&results)) {
    now = results.value;
    Serial.println(now);
    
    if(now==-1)
      now = last;
    
    switch(now){
      case -23971:
	if(red==0)
	  red=255;
	else
	  red--;
	break;
      case 25245:
	if(red==255)
	  red=0;
	else
	  red++;
	break;
      case 8925:
	if(green==0)
	  green=255;
	else
	  green--;
	break;
      case 765:
	if(green==255)
	  green=0;
	else
	  green++;
	break;
      case -8161:
	if(blue==0)
	  blue=255;
	else
	  blue--;
	break;
      case -22441:
	if(blue==255)
	  blue=0;
	else
	  blue++;
	break;
      case -7651:
	red=0;
	green=0;
	blue=0;
	break;
      default:break;
    }
    irrecv.resume();
    last = now;
  }
  
  color(red, green, blue);            
}

void color(int r, int g, int b){
  analogWrite(9, r);
  analogWrite(10, g);
  analogWrite(6, b);
}

机器人:俱乐部与实验室的差异

在大学里,我接触到了两个和机器人有关的地方:学生组建的机器人俱乐部,学校组织的机器人实验室。

这是两个不同群体的代表,在很多方面代表了深刻的差异。

机器人俱乐部是一个被兴趣驱动的群体,他们是非常社会化的。俱乐部的目标或许可以用其他语言来表示,但本质即是:自我的乐趣。不论是机器人带来的乐趣,还是这个过程产生的乐趣。我们是在玩机器人,不必去在意是否有用。

而实验室是有现实目的的,不论是研究成果,还是应用价值。被关注对象之外的东西牵制,导致这个过程逐渐模式化。引入工程管理方法,提高产出效率。这是在造机器人,有用的机器人。

MediaWiki MathJax数学公式

原理

MediaWiki的插件一般由php脚本和javascript脚本组成,直接上传到服务器,并在配置文件内添加插件路径即可使用。

Math插件的安装比较繁琐,因为它还依赖于其他本地应用程序,如mineTex。Math是一个统一化的接口,用户使用同样的数学公式代码,却可以通过不同方式生成公式。这些方式包括:PNG图片,LaTex,Tex,HTML,MathML等。而Math并没有实现这些功能的模块,需要调用其它应用程序。

目前默认的后端是Texvc,它可以生成PNG图片。这种方式需要服务器安装mineTex本地应用程序。然而对于共享空间上的站点来说,可能无法安装软件。PNG图片的显示效果也不好,在屏幕分辨率高的情况下不够清晰平滑,不能随文本缩放。因此,MediaWiki未来将会采用另一种表现更好的方式——Mathjax。

MathJax是一个开源的JavaScript数学公式显示引擎,适用于几乎所有现代浏览器。它被广泛应用于Wiki,WordPress博客等站点。使用它非常简单,只要在网页上的head标签内加入

<script type="text/javascript"
   src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>

即可。对于WordPress,MediaWiki等平台,若需要在整个站点启用此特性,则应在站点皮肤的HTML/PHP脚本中添加。

可以看出,这实际上是调用了MathJax在线引擎,JavaScript脚本存放于远程服务器上。若是在本地局域网内不能访问国际互联网,则可以下载MathJax并安装在本地,链接修改为本地站点。

步骤

对于MediaWiki,通过Math插件添加更加方便控制,且能应用于所有皮肤中。

第一步,下载Math插件

第二步,上传Math插件。将插件解压并将文件夹上传到extension目录中,命令文件夹为Math。

第三步,注册Math插件。打开LocalSettings.php,在插件注册部分添加:

require_once("$IP/extensions/Math/Math.php");

第四步,配置Math插件。打开/extensions/Math/Math.php,更改如下几条配置信息:
1.关闭Tex

$wgUseTeX = false;

2.开启MathJax

$wgUseMathJax = true;

3.设MathJax为默认

$wgDefaultUserOptions['math'] = MW_MATH_MATHJAX;

Math默认调用MathJax官方网站的引擎。若你在不连接国际互联网的情况下使用,或者希望使用自己的服务器提高效率,可以安装自己的MathJax引擎。

第一步,下载MathJax引擎

第二步,上传MathJax到服务器。

第三步,修改Math插件配置:

$wgMathJaxUrl = 'http://yoursite.org/mathjax/MathJax.js?config=TeX-AMS_HTML';

URL修改为你的MathJax引擎所在的位置。

对于学校内,企业内,组织内的网络系统,可以搭建一个开放MathJax引擎,供所有内部站点使用。

自定义名字空间及别名

名字空间的作用

名字空间可以理解为类似C++,Java的命名空间。名字空间能够对维基页面进行组织,划分页面的本质属性或者内容区分。这比页面分类更加显著,从名字便可以判断。名字空间还能够避免重名,如维基百科的“维基百科:首页”和“首页”就是不同的,一个是站点的首页,一个是名为“首页”的词条。

名字空间的原理

每一个名字空间都有自己唯一的ID,ID是不会变更的。这个ID是页面的属性,将页面绑定在这个名字空间内。而ID对应的名字空间的名字,则可以变化更改。若新建的名字空间与原来曾有的名字空间同名,并不会令那些页面转移到新名字空间下。就像一个人可以改自己的名字,但这个人的本质不变;当然,其他重名的人,也不是这个人。

名字空间具有名字和别名,就像一个人会有好几个名字。名字是默认显示的,而别名会链接到名字。别名让同一个名字空间具有多种书写方式,这样做的好处很多。首先如果你输入WP别名,会比输入Wikipedia更快,简写有时很有效;其次,可以避免混淆,误把近义词当作名字空间,结果没产生任何实际效果;还有就是本地化,中文用户可能更喜欢输入“分类:”“维基百科:”而不是“Category:”“Wikipedia:”。

MediaWiki具有一系列系统名字空间,比如主名字空间,帮助,项目,分类,模板,特殊及相应的讨论等等。这些名字空间不可更改。它们占据了0-99的名字空间ID,虽然并未全用。因此我们只能使用100以后的名字空间。

自定义名字空间

和大多数设置一样,自定义名字空间需要在LocalSettings.php里面完成。因此第一步就是打开站点的LocalSetting.php文件。

自定义设置一般都会写在配置文件的末尾,以免和系统默认设置混淆。加一段注释,如#Namespace Setting,会让配置文件更加清晰。

名字空间ID是整数,为了避免大意出错,通常会设置一个常量。因为一般会将名字空间和相应的讨论页名字空间定义在一起,所以它们总是成对出现。使用NS_前缀可以清晰地表达这个常量是一个名字空间ID。来看看下面这个例子:

define("NS_FOOL", 100);
define("NS_FOOL_TALK", 101);

然后就可以自定义新的名字空间了。

$wgExtraNamespaces[NS_FOOL] = "Fool";
$wgExtraNamespaces[NS_FOOL_TALK] = "Fool_talk";

如果你想要将这些名字空间设置为内容名字空间:

$wgContentNamespaces = array( NS_MAIN, NS_HELP, NS_FOOL, NS_TALK );

*这里的常量都代表着一个数字,NS_MAIN是0,NS_FOOL是100。
*内容名字空间和主名字空间本质相同,也会出现在主名字空间的搜索结果中。

这样,我们就为一对名字空间赋予了名字。以后在这些名字空间下创建的页面,会自动被归入相应的ID下。当名字空间的名字被修改后,那些页面也会随着变化。

最后,让我们来为它们添加别名。一个名字空间可以拥有无数多的别名,无论英文,中文还是保定话。

如果你只想设置一两个名字空间别名:

$wgNamespaceAliases['F'] = NS_FOOL;
$wgNamespaceAliases['F_talk'] = NS_FOOL_TALK;

如果你想设置一大堆名字空间别名:

$wgNamespaceAliases = array(
        'F' => NS_FOOL,
        '笨蛋' => NS_FOOL,
        '二傻' => NS_FOOL
    );

好了,现在维基站点就能够使用这些名字空间了,用名字和别名都可以。

为何对统一身份认证说不

当网络上出现了越来越多的站点,用户开始要注册大量的账户,记忆繁杂的用户名和密码。另一种局部的现象是,一个网站由多个子站点构成,各个独立的子站点需要对用户的需求提供统一的完善的服务。

于是,统一身份认证渐渐成为被广泛认同的解决方案。用户只需注册一次,便能用这个身份登录不同站点。各个站点通过共享用户信息,实现更一致更优秀的用户体验。

有人问我为什么ZJUBOT并未采用统一身份认证,用户访问问答、论坛和维基需要使用不同的帐号。我的回答是,为了避免某些问题。

统一身份认证确实是个有意义的创新,但它并非是万试灵药。我们不得不面对它本身带来的诸多问题。

首先是隐私泄露。每个站点的功能属性是不同的,问答网站、维基站点、在线论坛、网络博客各自有自己的特点。用户希望自己在网络博客上是实名的。他会在那里与很多认识的人分享东西,包含很多现实中的信息。而在论坛里,他不得不与很多不认识的人遭遇。他更愿意匿名,保护自己的隐私。然而统一身份认证将导致你在不同站点间的信息直接互相传递,这增加了隐私外泄的风险。我们不得不考虑这些站点隐私保护程度的差异,规避这种风险。

其次是管理的难度。在Mediawiki站点,我们通常不允许一个真实用户注册多个用户账户。我们必须警惕每个用户账户的身份,防止破坏者通过傀儡账户持续破坏。然而对于论坛来说,一个人拥有多个账户不是什么坏事,与人交流有时不得不采用其他身份。对于官方博客,可能只有少数成员有操作权限,并且使用真名。而一个问答网站,则可能允许匿名用户使用。统一身份认证带来的麻烦是,如果管理员需要用封禁的方式防控破坏,那么他就不得不让其他站点受到同样严格的限制。

对用户来说,统一身份认证虽然带来了使用的便利,却带来了不小的风险。当所有信息都被挂钩,现实中的人在网络上也很容易被定位。就像很多大学的论坛,用户注册使用学号的统一身份认证——我在论坛里发了一些有些激进的言论,第二天就被老师约去喝茶。

这种便利不是无偿的,统一身份认证也不单纯是一个使用方式的改变。虚拟身份如何得到保护,虚拟与现实的关系,是我们应当思考的。