最近用MediaWiki建立了一个图书库,主要就是依靠Cargo的语义化功能。只是呢,随着需求的调整,碰到点新问题。
在设计的时候,其实我已经为尽量避免产生歧义而新创建了一个命名空间,但是在处理同一本书不同版本时还是没有特别好的解决方案。
百度百科的思路貌似是将同名的条目作为子页面挂在主页面下。OK,借鉴一下思路,但凡有不同版本的都变为子页面,然后在主页面上做聚合,类似如下的:
Different-Editions-of-Books.png
图中两本书的页面分别为出版物:改变心理学的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), ')]]')

思路就是将/右侧的内容截取出来后,再截取左侧的字符串。

最后修改:2021 年 08 月 06 日 10 : 02 AM
如果觉得我的文章对你有用,请随意赞赏