最近用MediaWiki建立了一个图书库,主要就是依靠Cargo的语义化功能。只是呢,随着需求的调整,碰到点新问题。
在设计的时候,其实我已经为尽量避免产生歧义而新创建了一个命名空间,但是在处理同一本书不同版本时还是没有特别好的解决方案。
百度百科的思路貌似是将同名的条目作为子页面挂在主页面下。OK,借鉴一下思路,但凡有不同版本的都变为子页面,然后在主页面上做聚合,类似如下的:
图中两本书的页面分别为出版物:改变心理学的40项研究/第5版
和出版物:改变心理学的40项研究/第7版
。如果要像图中显示的那样,既保持链接又保持显示xxx书(第x版)
的样式,就得在Cargo查询时对字段进行适当的调整——也就是将页面标题(PageTitle)中/
前的字符串保留,而/
后的字符串在前后加上中文括号。
Cargo的文档中有说明可以使用SQL函数,只是有很多是默认没有开启的。比如我想使用LEFT()
函数,就必须在LocalSettings.php
中开启,如下:
$wgCargoAllowedSQLFunctions[] = 'LEFT';
如果没有开启,页面则会提示:
错误:SQL函数“LEFT()”不允许。
刚开始参考网上截取字符串的文章,使用了CHARINDEX()
函数,虽然在配置文件中开启了,但是提示错误如下:
Error 1305: FUNCTION CHARINDEX does not exist (localhost)
原来,CHARINDEX()
函数只适用于SQL-SERVER语句中,并不适合MYSQL。
在MYSQL中,最简单的方法就是采用SUBSTRING_INDEX()
函数。
好吧,先启用函数试试:
$wgCargoAllowedSQLFunctions[] = 'SUBSTRING_INDEX';
尝试用截取一下,具体代码如下:
CONCAT( '[[', _pageName, '|', SUBSTRING_INDEX(_pageTitle, '/', 1), '(', SUBSTRING_INDEX(_pageTitle, '/', -1), ')]]')
其中CONCAT()用于合成字符串,具体参考《MeidaWiki教程之Cargo篇》一文中的自定义链接文本
章节。图中的效果终于实现。
OK,还有一种更加复杂的情况:同一本书的版次也是一样,但由于出版社不一样,那么封面和ISBN就不一样了。按照上面的思路,要么就是在版次后面用/
或者括号添加出版社以示区别,在这里我采用后者,页面形式变为出版物:津巴多普通心理学/第7版(机械工业出版社)
。那么用上述的方式截取,标题会变成津巴多普通心理学(第7版(机械工业出版社))
。
继续截取,通过识别左括号直接截取掉后面的内容(这也是为什么我选用括号而不是/
,方便识别截取),代码如下:
CONCAT( '[[', _pageName, '|', SUBSTRING_INDEX(_pageTitle, '/', 1), '(', SUBSTRING_INDEX(SUBSTRING_INDEX(_pageTitle, '/', -1),'(', 1), ')]]')
思路就是将/
右侧的内容截取出来后,再截取(
左侧的字符串。