カテゴリ | |
---|---|
サマリ | 階層下のページもオートリンクしたい(AutoBaseAlias 機能) |
バージョン | 1.4.7 |
投稿者 | こしまえ |
状態 | 完了 |
投稿日 | 2009-03-14 (土) 04:46:26 |
例えば
aaa aaa/bbb/ aaa/bbb/ccc aaa/bbb/ddd aaa/bbb/ddd/
というページがあったとして、aaaにはオートリンクをしてくれますが、それ以降はしてくれません。 そこで bbbでaaa/bbbにオートリンク、cccでaaa/bbb/cccにオートリンクしてくれることはできないでしょうか? もしもページ名がかぶった場合はリンクをクリックした時にユーザーがリンクを選択できる形だととても便利だと思います。 plusの方では可能らしいのですが、本家でも使えるかと思い、質問してみました。 質問箱/4436の方法でAutoAliasは導入したんですが、上記の機能の差分をAutoBaseAlias: AutoAlias にページ名の basename を自動的に設定する機能の追加からそのまま適用してみてもエラーで機能しませんでした。
Fatal error: Call to undefined function get_short_pagename() in /lib/file.php on line 513 $base = get_short_pagename($page);←エラーの行です。これだけだったのですが、何かわかりますでしょうか?追記でfunc.phpの差分を適用した場合はAutoAliasが無効(適用する前はちゃんと動作し、差分を適用した場合はリンクから「AutoAlias名」といった未作成状態)になってしまいました。 -- こしまえ 2009-03-16 (月) 00:21:00
[[別名>本名]]とした時に、1つの別名に複数の本名を許すのかどうかという違いです。
return $paren ? '(' . $date . ')' : $date; } +// Get short pagename(last token without '/') +function get_short_pagename($fullpagename) +{ + $pagestack = explode('/', $fullpagename); + return array_pop($pagestack); +} // Get short string of the passage, 'N seconds/minutes/hours/days/years ago'としてみました。これだけで大丈夫かどうかわからなのかったのですが、とりあえずエラーは出なくなりました。
if (! is_page($page)) { $realpages = get_autoaliases(strip_bracket($page)); foreach ($realpages as $realpage) { if (is_page($realpage)) { $page = $realpage; break; } } }というように、リンク先のページがなかった場合にエイリアスの判定しています。(上にも同じ様な事が書いてありますが、)これをAutoAlias でだけ判定させるために上で書き換えた場所に組み込むのか、それともplus に近づけるのか、ですね。 -- 2009-03-17 (火) 16:54:33
global $script, $vars, $link_compact, $related, $_symbol_noexists; $s_page = htmlspecialchars(strip_bracket($page)); + if (! is_page($page)) { + $realpages = get_autoaliases(strip_bracket($page)); + foreach ($realpages as $realpage) { + if (is_page($realpage)) { + $page = $realpage; + break; + } + } + } $s_alias = ($alias == '') ? $s_page : $alias;link.php のlinks_init()も、また新たに表記するのもあれなので前回記述した場所を修正してみました。この2箇所を修正したところ、前回の状態と変化は無く、エラーも出ていない状態となりました。 -- こしまえ 2009-03-17 (火) 20:34:08
あいうえおabcかきくけこと本来なら表示されるところ
あいうえおかきくけこと表示されます。一応最初のplusの差分を導入した経緯を書きますと
pukiwiki.ini.php +$autobasealias = 1; + +// nonlist for AutoBaseAlias +$autobasealias_nonlist = '^\:|(^|\/)template$';file.php.diffはそのまま差分を適用し、func.php.diffは
$pairs[$name] = array_unique($pairs[$name]); } } - - // An array: All pairs - if ($word === '') return $pairs; - - // A string: Seek the pair - return isset($pairs[$word]) ? $pairs[$word] : array(); + return $pairs; }上記が見あたらなかったので適用せずにスルーしています。 -- こしまえ 2009-03-17 (火) 23:18:41
function toString() { $this->alias = get_autoaliases($this->name); if (! empty($this->aliases)) { $link = '[[' . $this->name . ']]'; return make_link($link); } return ''; }のように結果を入れた変数とは違うものを判定に使っていませんか?
if ($word === '') { // An array(): All pairs return $pairs; } else { // A string: Seek the pair if (isset($pairs[$word])) { return $pairs[$word]; } else { return ''; } }という形にPukiWiki ではなっています。(plus 用の差分を当てようとしているので、こういう違いがいくつかあります)
- if ($word === '') { - // An array(): All pairs - return $pairs; - } else { - // A string: Seek the pair - if (isset($pairs[$word])) { - return $pairs[$word]; - } else { - return ''; - } + return $pairs;としてみたところ、autoalias.datは生成されるようになりましたが、「abc」状態になってしまいました。空白では無くなったのでたぶん良くなっているとは思います。
あいうえおabc?かきくけこccc?さしすせそと、このような形になっています。 リンクの形は前者の1つの場合はそこに自動で飛び、複数の場合は一覧表示をと思っております。 -- こしまえ 2009-03-18 (水) 21:12:38
} else { // Dangling link if (PKWK_READONLY) return $s_alias; // No dacorations $retval = $s_alias . '<a href="' . $script . '?cmd=edit&page=' . $r_page . $r_refer . '">' . $_symbol_noexists . '</a>'; if ($link_compact) { return $retval; } else { return '<span class="noexists">' . $retval . '</span>'; } }という部分があると思います。?cmd=edit とあるので想像がつくと思いますが、$retval にabc? という形のリンクを代入しています。edit → read への書き換えはすぐにできると思いますが、abc のような形に変えたいのなら質問箱/4042 を参考にしてください。 -- 2009-03-18 (水) 22:50:47
[[google>http://www.google.co.jp/]] [[グーグル>http://www.google.co.jp/]]とした場合、google or グーグルと記入しただけで両方の文字を自動でhttp://www.google.co.jp/にワンクッションおかずに直接リンクを張ってくれるような形が理想です。
if ($page == '') return '<a href="' . $anchor . '">' . $s_alias . '</a>'; + + if (! is_page($page)) { + $realpages = get_autoaliases(strip_bracket($page)); + if (count($realpages) === 1) { + $realpage = $realpages[0]; + if (is_pagename($realpage)) { + $page = $realpage; + } else { + $link = '[[' . $s_alias . '>' . $realpage . ']]'; + return make_link($link); + } + } + } $r_page = rawurlencode($page);これで、大半の場合はうまくいくと思います。 -- 2009-03-20 (金) 00:01:42
function toString() { $this->aliases = get_autoaliases($this->name); if (! empty($this->aliases)) { if (is_pagename($this->name)) { $link = '[[' . $this->name . ']]'; return make_link($link); } else { $realpage = $this->aliases[0]; $link = '[[' . $this->name . '>' . $realpage . ']]'; return make_link($link); } } return ''; }のようにすると、ひとまず解決です。ただ、このままだとエイリアスの数を無視してしまう(こしまえ さんの希望とは違ってしまう)ので、ページ名でない方の分岐にすぐ上で挙げたmake_pagelink() の修正をうまくいれてください。ページ名の場合は、BracketName 経由でmake_pagelink() に進み、そこで候補のチェックをするのでそのままでかまいません。 -- 2009-03-20 (金) 00:01:42
下記はAutoAliasでの設定で、?はreadで作成画面へのリンクです [[google>http://www.google.co.jp/]] [[zzz>aaa]] [[zzzz>aaa]] [[yyy>xxx]] 下記は結果です google? abc ○ bbb リンクは作成されましたがリンク先は選択では無く、bbbのみに abc/bbb ○ zzz リンクは作成されましたが、指定したaaaでは無くabc/aaaへリンクに zzzz? yyy?との結果になりました。?の新規作成リンクをクリックすると、googleなら「h」の編集画面、zzzzなら「a」の編集画面、yyyなら「x」の編集画面になりました。
- function toString() - { - $this->aliases = get_autoaliases($this->name); - if (! empty($this->aliases)) { - $link = '[[' . $this->name . ']]'; - return make_link($link); - } - return ''; - } + function toString() + { + $this->aliases = get_autoaliases($this->name); + if (! empty($this->aliases)) { + if (is_pagename($this->name)) { + $link = '[[' . $this->name . ']]'; + return make_link($link); + } else { + $realpage = $this->aliases[0]; + $link = '[[' . $this->name . '>' . $realpage . ']]'; + return make_link($link); + } + } + return ''; + }としたところ、特に変化はありませんでした。
} else if (! auth::check_role('safemode') && is_interwiki($page)) {でエラーが出ますので、
} else if (! PKWK_SAFE_MODE && is_interwiki($page)) {にしてとりあえず動くようになりましたが、修正前と修正後の変化はないようでした。
} elseif (is_url($realpage)) { header('HTTP/1.0 301 Moved Permanently'); header('Location: ' . $realpage); return; } elseif (is_interwiki($realpage)) { header('HTTP/1.0 301 Moved Permanently'); $vars['page'] = $realpage; return do_plugin_action('interwiki'); // header('Location');上記をいじるんだと思ったのですが、リターンの中身を単純に消去するといいのとかと思って試したんですが変化がありませんでしたので、それ以前のどこかがやはりうまくできてないのでしょうか。 -- こしまえ 2009-03-20 (金) 00:40:28
google ○ abc ○ bbb リンクは作成されましたがリンク先は選択では無く、bbbのみに abc/bbb ○ zzz リンクは作成されましたが、指定したaaaでは無くabc/aaaへリンクに zzzz ○ yyy ○となりました。次に
$page = isset($vars['page']) ? $vars['page'] : ''; + if (count($realpages) >= 2) { + $body = '<p>'; + $body .= _('This pagename is an alias to') . '<br />'; + $link = ''; + foreach ($realpages as $realpage) { + $link .= '[[' . $realpage . '>' . $realpage . ']]&br;'; + } + $body .= make_link($link); + $body .= '</p>'; + return array('msg'=>_('Redirect'), 'body'=>$body); + }と、一番前に持ってきたつもりなのですが、機能してくれませんでした。
function toString() { $this->aliases = get_autoaliases($this->name); if (! empty($this->aliases)) { if (is_pagename($this->name)) { $link = '[[' . $this->name . ']]'; return make_link($link); } else { $realpage = $this->aliases[0]; $link = '[[' . $this->name . '>' . $realpage . ']]'; return make_link($link); } } return ''; }修正とは、上記にbbb とabc/bbbというページ(bbbが2つ)があった場合にread.inc.phpを呼び出すというのを追加しないといけないのかなと思ったんですが、2009-03-20 (金) 00:01:42のmake_pagelinkをどうにかいれてみても失敗でよくわからないところでエラーとなりました。
1[[http://www.google.co.jp/]] 2[[http://www.google.co.jp/>http://www.google.co.jp/]]これはページ名でない方の分岐との関係なのでしょうか?
$realpage = $this->aliases[0]; $link = '[[' . $this->name . '>' . $realpage . ']]'; return make_link($link); + } else { + $link = '[[' . $s_alias . '>' . $realpage . ']]'; + return make_link($read);ちょっと何かとごっちゃになってきて混乱しておりますが、間違っていたらすいません。 -- こしまえ 2009-03-20 (金) 16:09:34
[[Q&A]]と変換され、[[Q&A]] と表示されるだけになってしまうのを防げるようになるだけです。 -- 2009-03-20 (金) 20:30:12
$page = isset($vars['page']) ? $vars['page'] : ''; if (! PKWK_SAFE_MODE && is_interwiki($page)) { return do_plugin_action('interwiki'); // InterWikiNameを処理 } $realpages = array(); if (is_page($page)) { $realpages[] = $page; } if (is_pagename($page)) { $realpages = array_merge($realpages, get_autoaliases($page)); }とした後で数をかぞえる、でしょうか?(未テスト)
function toString() { $this->aliases = get_autoaliases($this->name); if (! empty($this->aliases)) { if (is_pagename($this->name)) { $link = '[[' . $this->name . ']]'; return make_link($link); } else { return htmlspecialchars($this->name); } } return ''; }で直ったりしますか?そのかわり、これだとAutoAlias の別名に半角の& や" を設定できなくなりますけど。(しても変換されない)
function toString() { $this->aliases = get_autoaliases($this->name); if (! empty($this->aliases)) { return make_pagelink($this->name, '', '',$this->page); } return ''; }とするのはアリなのかな・・・?? -- 2009-03-20 (金) 23:37:55
[[Q&A>Q&A]]というルールを作成したのですが2009-03-20 (金) 00:01:42のtoString()の状態でQ&Aの半角&を使える状態を確認しました。
// AutoAlias class Link_autoalias extends Linkの部分ですので、場所は間違えてはないとは思うのですが、もしも違う場所を修正しているといけませんので記載しておきました。
if (count($realpages) === 1) { $realpage = $realpages[0]; $link = '[[' . $s_alias . '>' . $realpage . ']]'; return make_link($link); } }みたいなことをしない限り、発生しないはずなんですが。(この場合、$realpage がページ名の場合またmake_pagelink() に戻ってくる) -- 2009-03-21 (土) 07:24:00
1. | ページが存在した場合は、必ずそれを表示する |
2. | セーフモードでない場合でInterWiki が送られてきた場合は、それのリダイレクトをトライする |
3. | (1. でページがないことはチェック済み)ページ名が送られてきた場合、エイリアス候補のチェック後、各処理をする |
4. | 1. ~3. に該当しなかった場合、無効なページ名としてエラーメッセージを返す |
$count = count($realpages); if ($count == 1) { $link = $realpages[0]; if (is_page($link)) { // ページを表示 check_readable($page, true, true); header_lastmod($page); return array('msg'=>'', 'body'=>''); } } if ($count >= 1) { // エイリアス候補がある場合(リダイレクトしなかった場合を含む)、一覧表示 $body = '<p>'; $body .= 'This pagename is an alias to<br />'; $link = ''; foreach ($realpages as $realpage) { $link .= '[[' . $realpage . '>' . $realpage . ']]&br;'; } if (is_pagename($page)) { // 有効なページ名への編集リンクを追加 $link .= '[[edit: ' . $page . '>'; $link .= get_script_uri() . '?cmd=edit&page=' . rawurlencode($page) . ']]'; } $body .= make_link($link); $body .= '</p>'; return array('msg'=>'Redirect', 'body'=>$body); } if (is_pagename($page)) { // 有効なページ名で存在しない場合、直接編集フォームに飛ばす header('Location: ' . get_script_uri() . '?cmd=edit&page=' . rawurlencode($link)); exit; } // 無効なページ名 return array( 'msg'=>$_title_invalidwn, 'body'=>str_replace('$1', htmlspecialchars($page), str_replace('$2', 'WikiName', $_msg_invalidiwn)) );という感じに続けたもの(今までの形を捨てたもの)なのですが、
[[ggg>hhh]] [[hhh>ggg]] [[ppp>ppp]]というような、ループしそうなAutoAlias を設定してからテストしていないから助かっているだけ、という訳ではないですよね?
[[ggg>hhh]] (hhhは存在する) [[hhh>ggg]] (gggは存在しない) [[ppp>ppp]] (pppは存在する)とした場合、特にループはおきませんでした。&br: そしてここから存在しないgggというページを作ろうとした時(readを修正前のplusの状態)
header('Location: ' . get_page_location_uri($realpage));この行でエラーが出るので作成できませんでした。他の関係の無いページを新規作成は可能です。
header('Location: ' . get_page_location_uri($realpage));は
header('Location: ' . get_script_uri() . '?' . rawurlencode($realpage));と同じです。 -- 2009-03-21 (土) 17:34:10
$link = ''; $script = get_script_uri(); foreach ($realpages as $realpage) { if (is_pagename($realpage)) { $link .= '[[' . $realpage . '>' . $script; $link .= '?cmd=read2&page=' . rawurlencode($realpage) . ']]&br;'; } else { $link .= '[[' . $realpage . '>' . $realpage . ']]&br;'; } }上は一部抜粋で書いてますが、候補がページ名ならread2 へのURL に、そうでなければページ中に書いたのと同じルールでリンクに、変換します。 -- 2009-03-21 (土) 19:54:29
aaa ○ abc/aaa ○ abc/bbb bbb?となり、?をクリックするとreadに飛んでabc/bbbとdef/bbbの一覧に def/bbb 上記と同じという結果となりました。この状態でbbbというページを新規作成しようとし、新規作成フォームでbbbと入力するとreadのabc/bbbとdef/bbbの一覧へとなりました。
下記はAutoAliasです [[google>http://www.google.co.jp/]] [[zzz>aaa]] [[zzzz>aaa]] [[yyy>xxx]] 下記は結果です zzz リンクは作成されましたが、指定したaaaでは無くabc/aaaへリンクに zzzz ○
つまり別名で指定した文字が階層下で実在(abc/zzzはありますが、zzzはありません)する場合、その文字をAutoAliasで設定しても、AutoAliasで指定した本名よりAutoBaseAliasの方が優先されてしまう。
という状態なのだと思います、今までこれを表記せずに質問なんてしたりして本当に申し訳ありません。
この違いで何かわかることがありましたら。
1. | ページ名が空の場合、そのページのアンカーへのリンクに |
2. | ページが存在しない場合、候補を呼び出し処理をする |
3. | AutoLink が作ったリンクの場合、ページが存在にかかわらず通常リンクになる または そのページが存在する場合、通常リンクになる |
4. | 3. に該当しない場合、Dangling link (「abc?」の形)になる |
if (! is_page($page)) { $realpages = get_autoaliases(strip_bracket($page)); + if (count($realpages) >= 1) { + $isautolink = TRUE; + } if (count($realpages) === 1) { $realpage = $realpages[0];候補がある場合、AutoLink が作ったリンクという事にしてしまって、通常リンクにしてしまおうというセコ技です。($anchor をリセットしたほうがいいかも)
// Dangling link if (PKWK_READONLY) return $s_alias; // No dacorations $retval = '<a href="' . $script . '?cmd=read&page=' . $r_page . $r_refer . '">' . $s_alias . '</a>'; if ($link_compact) { return $retval; } else { return '<span class="noexists">' . $retval . '</span>'; }となっておりますが、ここに分岐(実在するページは無いがAutoBaseAlias候補が複数ある場合?)などを作れたらと思いました。
array(28) { ["zzz"]=> array(1) { [0]=> string(7) "abc/zzz" }となりました。
["zzz"]=> array(2) { [0]=> string(3) "aaa" [1]=> string(7) "abc/zzz" }になりませんか・・・。今度はget_autoaliases_from_aliaspage() の結果を表示してみてください。
array(14) { ["zzz"]=> array(1) { [0]=> string(3) "aaa" }となっておりました。
// Load/get autoalias pairs function get_autoaliases($word = '') { global $autobasealias; static $pairs; if (! isset($pairs)) { $pairs = get_autoaliases_from_aliaspage(); if ($autobasealias) { - $pairs = array_merge($pairs, get_autoaliases_from_autobasealias()); + $pairs = array_merge_recursive($pairs, get_autoaliases_from_autobasealias()); } }と、してみたのですがリンクは「zzz→abc/bbb」から、「zzz?となって?をクリックするとreadに飛んで、一覧にaaa,abc/zzzの2つが表示」の状態となりました。
["zzz"]=> array(2) { [0]=> string(3) "aaa" [1]=> string(7) "abc/zzz" } array(14) { ["zzz"]=> array(1) { [0]=> string(3) "aaa" }となっていたので、この部分は変化無しということでした。