1

テキスト編集を行い、wiki のようなリンクを許可する Rails アプリケーションがあります。説明に [[:slug]] と書くと、関連するページへのリンクが生成され、リンク テキストはデータベースに保存された名前になります。[[:slug |[:slug | Some Text]] で、リンクには名前の代わりに「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
4

1 に答える 1

2

Railsと文字列スキャンの正規表現について調査した後、私の質問に対する答えを思いつきました。これが私が今使っているメソッドのコードです:

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]]の両方の形式のリンクがある場合は、2つの別々の呼び出しを行う必要がありました。そのため、charactersというメソッドに変数を追加しました。これは、データベース全体を検索する代わりに、メソッドを呼び出す場所から文字の配列を渡すことができるようにするためです。これは、コストがかかる可能性があり、使用する文字のリストがすでにわかっているためです。

于 2012-09-25T08:42:33.717 に答える