■
はてなの「キーワード自動リンク」みたいなヤツを実現するには、どうすればいいか。
キーワードをXMLファイルに取り置くことにしました。
そのXMLファイルを読んで、特定の場所に存在するキーワードを、リンクに変換すればいいわけです。
「anchored」というグローバルフィルタを作ってみました。ただし、ベータ版。
package MT::Plugin::Anchored; use strict; use MT; use MT::Template::Context; use MT::Plugin; use LWP::Simple; # show plugin information to main menu my $plugin = MT::Plugin->new; $plugin->name('Anchored 0.01'); $plugin->description('Add anchors(from xml data) to string.<br />xml data : &lt;keyword&gt;keyword&lt;/keyword&gt;&lt;url&gt;url&lt;/url&gt;&lt;title&gt;title&lt;/title&gt;...<br />usage : &lt;$MTEntryBody anchored="http://xmlpath"$&gt;'); MT->add_plugin($plugin); # add global filter MT::Template::Context->add_global_filter(anchored => \&anchored); # main sub anchored { my ($text, $arg, $ctx) = @_; my ($keyword, $url, $title, $anchored); if($arg ne '') { # Get xml data my $xmlbuf = get($arg); my $pattern = "<keyword>(.+?)</keyword>.*?<url>(.+?)</url>.*?<title>(.+?)</title>"; my (%urltable,%titletable,%scoretable); # Construct hash table like 'keyword => url' and 'keyword => title' while($xmlbuf =~ /$pattern/gs) { $urltable{$1} = $2; $titletable{$1} = $3; $scoretable{$1} = 0; } # Add score foreach my $keyword1 (keys(%scoretable)) { foreach my $keyword2 (keys(%scoretable)) { if($keyword2 =~ /$keyword1/) { $scoretable{$keyword2}++; } } } # Add anchors my($text_tmp, $tag_tmp, $skip, $result, $tmpstr); my $dummystr = "<!--DUMMY-->"; foreach $keyword (sort {$scoretable{$b} <=> $scoretable{$a}} keys(%scoretable)) { $url = $urltable{$keyword}; $title = $titletable{$keyword}; $anchored = "<a href=\"".$url."\" title=\"".$title."\">".$keyword."</a>"; # Basic logic refered from http://www.din.or.jp/~ohzaki/perl.htm#AutoLink $skip = 0; $result = ''; $tmpstr = $text.$dummystr; while($tmpstr =~ /([^<]*?)(<.*?>)/gs) { last if $1 eq '' and $2 eq ''; $text_tmp = $1; $tag_tmp = $2; if($skip) { if($tag_tmp eq $dummystr) { $result .= $text_tmp; } else { $result .= $text_tmp.$tag_tmp; } if($tag_tmp =~ /^<\/[aA](?![0-9A-Za-z])/) { $skip = 0; } } else { $text_tmp =~ s/$keyword/$anchored/g; if($tag_tmp eq $dummystr) { $result .= $text_tmp; } else { $result .= $text_tmp.$tag_tmp; } if($tag_tmp =~ /^<[aA](?![0-9A-Za-z])/) { $skip = 1; } } } if($result ne '') { $text = $result; } } } $text; } 1;
これを「anchored.pl」などの名前で保存し、pluginsに入れます。
キーワード定義のXMLを用意します。
<?xml version="1.0" encoding="UTF-8"?> <Anchors> <Anchor> <keyword>Movable</keyword> <url>http://foobar/movable/</url> <title>Movableのページ</title> </Anchor> <Anchor> <keyword>Type</keyword> <url>http://foobar/type/</url> <title>Typeのページ</title> </Anchor> <Anchor> <keyword>Movable Type</keyword> <url>http://foobar/movabletype/</url> <title>Movable Typeのページ</title> </Anchor> </Anchors>
これを、keyword.xml 等に保存。
<$MTEntryBody anchored="http://foobar/keyword.xml"$>
と記述した場合、エントリー本文中のキーワードが、リンク付になります。
Movable Type --> <a href="http://foobar/movabletype/" title="Movable Typeのページ">Movable Type</a> Movable --> <a href="http://foobar/movable/" title="Movableのページ">Movable</a> Type --> <a href="http://foobar/type/" title="Typeのページ">Type</a>
XMLファイルの中身のキーワードが順不同でも、キーワードを勝手に重み付けします。
例えば「Movable Type」の変換前に、「Movable」や「Type」を変換しないようになっています。
MTEntryMoreなどにも使用できます。ただし、<script>タグがあった場合、不具合が出るかもしれません。
※需要があるかどうかは別として、ご利用になった場合に不具合が生じても、責任は負えません。自己責任でお願いいたします。