我有一个Rails应用程序,我正在进行文本编辑并允许类似wiki的链接。我已经能够使它工作,所以你可以在描述中编写[[:slug]],它将生成相关页面的链接,链接文本是保存在数据库中的名称。我想这样做,以便我可以写[[:slug |一些文字]]和链接会说“Some Text”而不是名字。另外,我想让它包含自定义链接文字。
这是我正在使用的代码。
def replace_slugs(text)
slugs = text.scan(/\[{2}:([^\]]*)\]{2}/).map{|s|s[0]}
Character.where(:slug => slugs).each{|ch| text.gsub!("[[:#{ch.slug}]]",
link_to(ch.name, adventure_character_path(ch.adventure, ch)))}
return text
end
答案 0 :(得分:2)
在对Rails和字符串扫描的regexp进行一些研究之后,我想出了一个问题的答案。这是我现在使用的方法的代码:
def replace_slugs(text, characters)
# Regexp that will recognize wiki urls with pipes and return 2 items
# It also ignores wiki urls that don't have a pipe
# /\[\[:([^|\]]*)?\|([^\]]+)\]\]/
links = text.scan(/\[\[:([^|\]]*)?\|([^\]]+)\]\]/)
for link in links do
slug = link[0]
title = link[1]
# I'm stripping out the whitespace when I do my find and for my link
# This makes it so you can have whitespace before and after the pipe
# e.g. [[:slug|Title]] [[:slug | Title]] [[:slug | Title]]
ch = characters.find_by_slug(slug.strip)
text.gsub!("[[:#{slug}|#{title}]]", link_to(title.strip,
adventure_character_path(ch.adventure, ch))) if ch
end
slugs = text.scan(/\[{2}:([^\]]*)\]{2}/).map{|s|s[0]}
characters.where(:slug => slugs).each{|ch| text.gsub!("[[:#{ch.slug}]]",
link_to(ch.name, adventure_character_path(ch.adventure, ch)))}
return text
end
由于我制定正则表达式的方式,当有[[:slug]]和[[:slug | Title]]形式的链接时,我不得不进行两次单独的调用。因此,我在名为characters的方法中添加了一个额外的变量。这样我就可以从我调用方法的地方传入一个字符数组,而不必搜索整个数据库,因为这可能会变得昂贵而且我已经知道了我想要使用的字符列表。