質問箱/4438

カテゴリ
サマリ階層下のページもオートリンクしたい(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 を自動的に設定する機能の追加からそのまま適用してみてもエラーで機能しませんでした。

回答

  • まさかとは思いますが、うえの2箇所のを両方とも追加したせいで「同じ関数名の定義がある」というエラーが出たんじゃあないですよね?get_autoaliases 関数とかで。 -- 2009-03-14 (土) 11:45:52
    • 「どんなエラーがどこに出たのか」が判らないと、詳しくアドバイスなんてできないんですが・・・ -- 2009-03-14 (土) 11:45:52
    • plus のBugTrack/121 で、dev:PukiWiki/1.4/ちょっと便利に/ページに別名をつける の修正も追加されている、という情報はいらないかな。(上のエラーとの関連がわからんし) -- 2009-03-14 (土) 11:45:52
  • 返信ありがとうございます。まずAutoAliasを先に導入し、これは特に問題なく動作しました。エラーの内容は500の内部サーバーエラーとなりました。file.php.diffの@@ -620,7 +635,37 @@を追加するとエラーが発生するようになり、ここを追加しないとエラーは発生しませんでした。(もちろん動作はしてくれません)
    他に気になる点といえばfunc.php.diffの@@ -762,12 +792,7 @@なんですが、本家では元から存在しない?っぽいのでここの行は適用していませんでした。そういえばplusはデフォルトで$autobasealiasの設定があるっぽいですが、本家にはないですよね。でも差分を見るとこの項目を追加するとも書いてないんですが、この1行も追加しないといけないんでしょうか?一応追加したんですがエラーは変わりませんでしたが。 -- こしまえ? 2009-03-14 (土) 16:10:32
  • サーバーエラーと同時にPHP のエラーが出ていたかはわからないのでしょうか?表示のさせ方がわからないのであればQ&A/インストール#x80b2883 をどうぞ。 -- 2009-03-14 (土) 21:45:01
  • URL先のを試してみたんですが「ページを表示できません」と変わらずでした。真っ白いエラーでは無く、前述のエラーが表示されます。php.iniが存在しないので、そちらの設定はできませんでした。 -- こしまえ? 2009-03-15 (日) 00:10:34
  • レンタルサーバか何かですか・・・。ログも見れないとなると、環境情報やどう修正したのかというソースそのものを挙げてもらわないと、再現実験は難しいですね・・・。 -- 2009-03-15 (日) 09:06:55
  • php.iniは自分で作成すれば大丈夫だったようで、作成してエラーをとってみました。
    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
  • 適当な英語訳「get_short_pagename() という未定義の関数が、/lib/file.php の513行目で呼ばれている」。この関数はPukiWiki plus! が独自追加した関数なので、PukiWiki にはありません。なので、[[plus のlib/func.php>http://svn.cafelounge.net/viewvc/pukiwiki-plus-i18n/trunk/lib/func.php?view=log]] からコピーする必要があります。 -- 2009-03-16 (月) 07:40:04
    • 他にも大きな違いがあって、PukiWiki のget_autoaliases() は$word が指定されたときに文字列を返しますが、plus は配列を返します。AutoAlias がうまく動かなくなったのはおそらくコレが理由でしょう。(上のエラーが出なくなって他に重大なエラーがなければ、コレ関連のエラーが出るようになるでしょう コレはエラーが出ません)
      これは
      [[別名>本名]]
      とした時に、1つの別名に複数の本名を許すのかどうかという違いです。
      plus の方はdev:PukiWiki/1.4/ちょっと便利に/ページに別名をつける*1 が入っているので、そのために配列を使ってリストを返すようになっています。
      対してPukiWiki は、この機能がデフォルトでは導入されていないので最初の1つさえ得られればよく、2つ目以降は使わないのでこのような形になっています。 -- 2009-03-16 (月) 07:40:04
    • さらにもう1つ、make_pagelink() が違います。plus はページが存在しなかったときに自動でエイリアス(AutoBaseAlias を含む)を参照して、設定されている場合は(複数設定があっても)最初の本名へのリンクにしてしまいます。
      この辺は、[[plus のlib/make_link.php>http://svn.cafelounge.net/viewvc/pukiwiki-plus-i18n/trunk/lib/make_link.php?view=log]] と比較してどう違いを吸収するのか(自分が必要としているのは何なのか*2) しだいですね。 -- 2009-03-16 (月) 07:40:04
  • 細かい説明ありがとうございます。[[plus のlib/func.php>http://svn.cafelounge.net/viewvc/pukiwiki-plus-i18n/trunk/lib/func.php?view=log]]から下記を追記
    	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'
    としてみました。これだけで大丈夫かどうかわからなのかったのですが、とりあえずエラーは出なくなりました。
    しかしAutoBaseAlias.datは生成されるんですが、機能はしていないようです。AutoAliasも変わらず機能していないのですが、エラーはひとつもでない状態です。
    Sonotsさんのread.inc.phpの本家用差分も適用したんですが、これを適用すると編集自体できなくなってしまいました、これもエラーが記録されることはありませんでした。 -- こしまえ? 2009-03-16 (月) 19:03:34
  • すみません、一部間違いを書いてました。エラーが出ずに、[[配列から文字列Array へ変換される>http://jp2.php.net/manual/ja/language.types.string.php#language.types.string.casting]]ので、Array へのリンクになっていると思います。 -- 2009-03-16 (月) 21:20:30
    • お詫びに修正方法の指針を。1つはPukiWiki に合わせて、get_autoaliases() に$word が指定されたときに文字列を返すようにしてしまう方法。もう1つはplus に合わせて受け手を配列で返すようにする方法です。
      前者の場合は、get_autoaliases() を修正すれば使えるようになるものの、ページに別名を~ の機能を導入しにくくなってしまいます。
      対して後者の場合、パラメータを指定してget_autoaliases() を呼び出している場所*3すべてを修正する必要があります。 -- 2009-03-16 (月) 21:20:30
    • どっちも欲しいという場合は、get_autoaliases() が受け付けるパラメータを1つ増やして切り替えできるようにする、というのもありかもしれません。もちろん、デフォルトはPukiWiki 寄りで。(修正箇所が増えるから) -- 2009-03-16 (月) 21:20:30
  • 試してみたところArrayになっていました。しかしリンク先をみたんですが、正直自分の知恵では修正方法が何一つ理解できませんでした。lib/link.phpに2箇所、lib/make_link.phpに1箇所にget_autoaliasesという文字列があるのは確認できたのですが、この文字列周辺をplusの最新版からコピペしてみたところ、特に変化はありませんでした。 -- こしまえ? 2009-03-17 (火) 01:59:12
    • (話が長くなってきたので、コピペ作業の差分を非表示中。見たい方はこのページのソースを覗いて下さい。)
  • plus に近づける方法を選んだのですね。その場合、ここでmake_pagelink() の違いが表に出てきます。PukiWiki はmake_link.php の上で消した場所でエイリアス先のリンクを決定しています*4が、
    plus はmake_pagelink() の中で
    	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
    • ついでに、link.php のlinks_init() への書き換えなんですが、$ref にデータを追加する部分を完全に消してしまっているので、links プラグインを使ってここを呼び出した場合に、related プラグインなどで使っているref キャッシュファイルが作成されなくなりますよ。links_update() への書き換えは大丈夫そうです。 -- 2009-03-17 (火) 16:54:33
  • 連日お返事ありがとうございます。少しさかのぼってみたんですが、希望としてはSonotsさんのread.inc.phpを導入して、最初の本名へのリンクをさせずに、複数本名がかぶる場合はリンクをユーザーが選ぶ形がよさそうですね。
    これを導入できればWikiName、BracketName 、AutoLink、AutoAliasの全てのリンク(BracketNameでは[ [aaa>aaa/bbb/aaa] ]とした場合はリンク選択は出さずに前記のリンクが適用される)になると理想的です。
    とりあえず指摘された箇所と
    	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
  • そういえば確認していませんでしたが、変化なしということは今もArray へのリンクになっているということですか?もしそうならlib/make_link.php の修正が効いていないということになります。$link = '[[' . $this->name . ']]'; とした時点で「AutoAlias = 別名への自動リンク」になっているはずですが。
    link.php への修正は、関連したプラグインや機能を使っていない限り基本的には関係ないんで、リンクの状態には影響しません。 -- 2009-03-17 (火) 22:38:06
    • あと、別名から本名への置き換えが必要なければ、上で挙げたmake_pagelink() への修正は必要ないかもしれません。その代わりに、ページがない場合はedit プラグインへのリンクになってしまうのを、read プラグインへのリンクにしてしまってsonots さんのread.inc.php へ送る方が都合がいいかもしれません。(好みの問題ですけど) -- 2009-03-17 (火) 22:57:31
  • そういえば報告を忘れていました。まず何もいじってない状態(AutoAlias導入のみ)ですと普通にAutoAliasで設定(ここではabc>aaa/bbb/abcとします)するとabcでAutoAliasが機能してくれます。
    plusの差分をあてた状態ですと「abc?」となり、BracketNameではないんですが、リンク作成状態になり、作成しようと?からリンクをクリックしてedit画面になるとArrayの作成ページになります。
    そこからmake_link.phpで$link = '[[' . $this->name . ']]';にすると「abc?」なのはかわりませんでしたが、?からリンクをクリックして新規作成画面にいくとabcの新規ページ編集画面になりました。
    そこからif (! empty($this->aliases)) {のplusの差分を当てるとAutoAliasに設定している文字列が全て空白になってしまい、AutoAliasの文字列だけ何も表示されなくなってしまいます。
    あいうえお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
  • あれ?!、常に空白が返りますか?2009-03-17 (火) 01:59:12 に書かれた修正の通りなら、get_autoaliases($this->name) の結果を$this->aliases に入れて、それが空でない時(if (! empty($this->aliases)) )にリンクを作るはずなんですが。
    return ''; が必ず返るのなら、
    	function toString()
    	{
    		$this->alias = get_autoaliases($this->name);
    		if (! empty($this->aliases)) {
    			$link = '[[' . $this->name  . ']]';
    			return make_link($link);
    		}
    		return '';
    	}
    のように結果を入れた変数とは違うものを判定に使っていませんか?
    あるいは、autoalias.dat とautobasealias.dat の更新をしていないため、今のルールとは違う対象をリンクにしようとしているのかもしれません。データがきちんと追随しているのなら、そもそもreturn ''; へは行かないはずなのですが・・・。修正間違いの可能性のほうが高そうですが、念のため、修正後にautoalias.dat とautobasealias.dat を更新してみてください。 -- 2009-03-17 (火) 23:58:30
    • 消すべき相手は、
      	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 用の差分を当てようとしているので、こういう違いがいくつかあります)
      get_autoaliases_from_aliaspage() が最後に$pairs をreturn するように修正しているのなら問題ありません。この関数が何もreturn していない場合はautoalias.dat の生成データに問題がでますが。 -- 2009-03-18 (水) 00:08:30
  • autoalias.dat とautobasealias.datを削除してみたところ、autobasealias.datしか生成されませんでした。autoalias.datを削除したので、abcはリンクもAutoAliasも無く普通に表示されております。
    しかし今また差分を見比べているのですが、どこを修正し間違えたか発見できませんでした。
    plusの差分を見たところ、特に間違えてそうな箇所は見あたらなかったんですが、もう一度よく見てみます。 -- こしまえ? 2009-03-18 (水) 00:45:06
  • ということは、現在は何もreturnしていないということなのですね。
    -	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?」状態になってしまいました。空白では無くなったのでたぶん良くなっているとは思います。
    • 追記ですが、上記の差分を当てた場合、AutoBaseAliasもaaa/bbb/cccとした時、[]を使わずにccc?という状態になりました。 -- こしまえ? 2009-03-18 (水) 00:52:57
  • このページの文章ソースと表示状態が違うから判断しづらいのですが、自動で「abc」へのリンクと「ccc」へのリンクになったということでしょうか?(リンクにならず、[[abc]] と表示されているのではないですよね?)
    もしそうなら、基礎部分はほぼ完了です。後はページ中に表示されるリンクの形をlib/make_link.php で修正して、ページが存在しない&エイリアス候補が存在する時に一覧を表示するようにplugin/read.inc.php を修正するだけですね。 -- 2009-03-18 (水) 19:44:51
    • リンクの形についての質問ですが、AutoAlias やAutoBaseAlias で1つの別名に対して1つしか本名が設定されていない時は、PukiWiki と同じように自動で[[別名>本名]] に変換されて、本名へリンクするのをご希望でしょうか?それとも本名が1つであろうと複数であろうと、必ず一覧表示へのリンクになるほうがいいのでしょうか? -- 2009-03-18 (水) 19:44:51
  • まぎらわしくてすいません。まだAutoAliasとAutoBaseAliasのリンクは作成されずにリンク作成状態(abc?*5といった感じでエディットリンク)になっています。
    abcをAliasと設定、aaa/bbb/cccというページがある状態で
    あいうえおabc?かきくけこccc?さしすせそ
    と、このような形になっています。 リンクの形は前者の1つの場合はそこに自動で飛び、複数の場合は一覧表示をと思っております。 -- こしまえ? 2009-03-18 (水) 21:12:38
  • [[別名]] と書いたときと同じ状態になるのは、Link_autoalias クラスのtoString() でそのように修正したからですね。ページが存在しないときにedit プラグインへのリンクになるのはmake_pagelink() のデフォルトです。 -- 2009-03-18 (水) 22:50:47
    • リンクの形について、もう少し掘り下げさせてください。1対1の時に、本名がURL やInterWiki などページ名以外であっても自動でリンクにするのか、それともその場合は一覧表示へのリンクにしてワンクッション入れるのか、です。それぞれ一長一短ありますが、どちらを希望するのかで微妙に改造法がかわってくるので。 -- 2009-03-18 (水) 22:50:47
    • エイリアスの設定のあるなしやその数に関する分岐を後回しにして、まずはページが存在しない時もread プラグインへのリンクになるような修正法を。make_pagelink() の最後の方に
      	} else {
      		// Dangling link
      		if (PKWK_READONLY) return $s_alias; // No dacorations
      
      		$retval = $s_alias . '<a href="' .
      			$script . '?cmd=edit&amp;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
  • URLやInterWikiのページは作成しないかなと思っていたのですが、その必要が出てくる可能性もありますし、1対1の時は全てそのままワンクッションをいれずにリンクへ飛ばそうと考えております。
    用途を考えたのですが、ワンクッションをいれた場合のメリットが想像つきませんでした。普段この機能を使用していないので、想像力不足で申し訳ありません。
    (というのもページ名にURLを作成できるとはしりませんでした。http://で、/を使った時点で階層化されるので、ページには使えないと思っていました。
    &gt ;のように/の部分をどうにかするということなのでしょうか)
    make_pagelinkについてはeditからreadに変えまして、編集画面がreadになっていることを確認しました。指摘ありがとうございます。 -- こしまえ? 2009-03-18 (水) 23:18:35
  • しまった、誤解されてしまった。AutoAlias のルールに、[[pukiwiki>http://pukiwiki.sourceforge.jp/]] と登録した時にpukiwiki という文字(別名)をhttp://pukiwiki.sourceforge.jp/ へのリンクにするのか、というつもりで書いたんですが。(前に少し挙げたplus のソースそのままでは、本名が何個あるかに係わらず、最初に設定されている実在するページ名の場合だけリンクに変換し、それ以外では置き換えせずに別名へのリンクになるので)
    ちなみに、:(半角のコロン)をページ名に含めることは、(ページ名全体の最初か最後を除いて)基本的にできません。(例えば、コメント/:config というページ名はNG で、:config/コメント ならOK 。)
    仮に[[http://pukiwiki.sourceforge.jp/]] と書いた場合は、http という定義名のInterWiki ルールに//pukiwiki.sourceforge.jp/ を適用すると判断されてしまいます。 -- 2009-03-19 (木) 14:09:25
  • そういうことでしたか、変な勘違いをしてすいません。ということは例えばAutoAliasに
    [[google>http&#x3a;//www.google.co.jp/]]
    [[グーグル>http&#x3a;//www.google.co.jp/]]
    とした場合、google or グーグルと記入しただけで両方の文字を自動でhttp://www.google.co.jp/にワンクッションおかずに直接リンクを張ってくれるような形が理想です。
    コロンはページ名に使ったことなかったのですが、最初にでしか使えないのですね。デフォルトで:が最初につくページが見えないようなってたりするのはそういう用途も考えて作られてたんですね。
    InterWikiもURLと同じく、やはりワンクッションおかずにと考えております。 -- こしまえ? 2009-03-19 (木) 19:27:58
  • それでは、make_pagelink() に次のように追加してください。
     	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
    • 「大半の場合は~」と書いたのは、実は大きな穴が1つ残っているからです。AutoAlias を通した場合必ず[[別名]] という形にしているので、別名に「ページ名としては認められていない文字」を設定した場合におかしな動作になってしまう可能性があります。(例えば、[[Q&A>Q&A]] という設定をエイリアスに使う場合)
      これを避けるには、別名の値が入っている$this->name 変数がページ名かどうかのチェックをする必要があります。 -- 2009-03-20 (金) 00:01:42
      • Link_autoalias クラスのtoString() を
        	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
    • read プラグインの方ですが、get_autoaliases() の仕様をplus と同じ(常に配列を返す)にしてしまったので、本家用の差分をそのまま当てはめる事はできません。(だからといって、plus 用のをそのまま使う事もできないですが)
      他に、dev:PukiWiki/1.4/ちょっと便利に/ページに別名をつける から見ることのできる差分では、候補が1つの場合ページ名しかリダイレクトしませんが、最新の[[plus のplugin/read.inc.php>http://svn.cafelounge.net/viewvc/pukiwiki-plus-i18n/trunk/plugin/read.inc.php?view=log]]ではURL やInterWiki でもリダイレクトするようになっている*6 など違う点もあります。
      なので、どのような形を希望するのかをまた明確にしていく必要があります。 -- 2009-03-20 (金) 00:01:42
      • get_autoaliases() から受け取った配列をどう使うのかは、plus の差分(ソース)や今回挙げた修正法にヒントがあるので、まずは単純な形で試してみて、そこから最終的に希望する形に近づけてください。 -- 2009-03-20 (金) 00:01:42
  • 修正箇所の指摘ありがとうございます。念のため経過を書きながら結果がどうなったかを記しておこうと思います。
    前提として abc,bbb,abc.aaa,abc/aaa,abc/bbb,xxxというページがあったとします。まずmake_pagelink()の差分を当てましたら
    下記はAutoAliasでの設定で、?はreadで作成画面へのリンクです
    [[google>http&#x3a;//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」の編集画面になりました。
    どうやらAutoAliasで設定した本名の頭文字1文字の編集画面になってしまう様です。
    「ページ名としては認められていない文字」がURLに入ってると思いますので、googleについては指摘してもらった箇所を修正すればいけるかと思ったのですが、ここから
    -	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 '';
    +	}
    としたところ、特に変化はありませんでした。
    make_pagelinkの修正については、事前の修正が成功していない?と思ったんですが色々$link = '' . $s_alias . '?';などとやってみてもどうにも変化無しでした。
    readプラグインはとりあえずplusのをそのまま上書きしましたところ
    } else if (! auth::check_role('safemode') && is_interwiki($page)) {
    でエラーが出ますので、
    } else if (! PKWK_SAFE_MODE && is_interwiki($page)) {
    にしてとりあえず動くようになりましたが、修正前と修正後の変化はないようでした。
    現在と同じようにURLやInterWikiのリダイレクトはさせない(AutoAlias設定時は除く)ようにしようかと思っています。
    現在はplusのをそのままコピーペーストしているんですが、
    			} 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
  • plus 用の差分だと修正があたらない場所がまだあるのを見逃してました。plus のlib/func.php のget_autoaliases_from_aliaspage と差し替えたほうが早いような気がします。
    一番の違いとしては、$pairs[$name] に直接値を入れるのか、$paris[$name] = array() として配列にリストを入れるのか、です。ここだけplus 用になっていないせいで、$realpages[0] がキー0 の値ではなく、文字列の0番目(0 からスタートするので、つまりは1文字目)を返してました。 -- 2009-03-20 (金) 12:29:36
    • bbb とabc/bbb というページが実在したときに一覧表示にならないのはそういう順番(優先順位)で処理をしているからです。最初のif 条件で「その名前のページが実在しているのか」を判定し、存在している場合は認証チェックの後そのページを表示してしまいます。(エイリアスの判定を追加してるであろう場所に進まない)
      もしこれを避けたいなら$page をセットした直後にエイリアスの候補を呼び出し、最初に総合的に判断する形に変えなければ無理でしょう。 -- 2009-03-20 (金) 12:29:36
    • あくまで、別名にBracketName と認められない(ページ名で使えない)文字を使えるようにするもので、本名には[[別名>本名]] と書いてリンクになるものなら最初から問題ありません。
      これは、別名の中にインラインプラグインやURLも記述できるようにするために、別名に使える文字の禁止ルールが本名の禁止ルールよりも緩くなっているからです。 -- 2009-03-20 (金) 12:29:36
  • 本日も返答ありがとうございます、get_autoaliases_from_aliaspageの差分を当てましたら
    google ○
    abc ○
    bbb リンクは作成されましたがリンク先は選択では無く、bbbのみに
    abc/bbb ○
    zzz リンクは作成されましたが、指定したaaaでは無くabc/aaaへリンクに
    zzzz ○
    yyy ○
    となりました。次に
    >もしこれを避けたいなら$page をセットした直後にエイリアスの候補を呼び出し、最初に総合的に判断する形に変えなければ無理でしょう。
    とのことでしたので、plusのreadをそのまま持ってきて、上記のauth::check_role('safemode')はコメントアウトして本家の設定にし、
    	$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/]]とした時と同じ効果になるということですよね。
      1[[http&#x3a;//www.google.co.jp/]]
      2[[http&#x3a;//www.google.co.jp/>http&#x3a;//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
  • AutoAlias の設定で1の使い方はできません。2の使い方(別名にURL)も処理順の都合上できません。(URL をページ中に書くと、URL へのリンクになりAutoAlias 扱いはしない)
    あの修正は別名に半角の&" を使ってもきちんとエイリアスするようにする程度の効果しかありません。 例えば、別名に「Q&A」と設定すると
    [[Q&A]]
    と変換され、[[Q&A]] と表示されるだけになってしまうのを防げるようになるだけです。 -- 2009-03-20 (金) 20:30:12
    • read.inc.php ですが・・・、いつ$realpages をセットしているのでしょうか?その追加の仕方だと、$realpages が空なので何もせずに素通りしてしまいます。仮に$realpages = get_autoaliases(strip_bracket($page)); を設定していたとしても、bbb とabc/bbb というページが実在したときにabc/bbb に飛ぶだけになりそうです。(bbb のチェックをしていない) -- 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));
        	}	
        とした後で数をかぞえる、でしょうか?(未テスト)
        うまく処理しないと無限ループしたり、AutoAlias 導入前と同じ動作をしなかったり、と問題があるので注意が必要です。 -- 2009-03-20 (金) 20:30:12
    •  「zzz リンクは作成されましたが、指定したaaaでは無くabc/aaaへリンクに」となる理由は、zzz → aaa → abc/aaa と2回変換されているからかもしれません。
      ひょっとして、toString() への修正がまずいのかな・・・
      	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 の別名に半角の&" を設定できなくなりますけど。(しても変換されない)
      これで直らなかったら、(キャッシュが正常という前提なら)make_pagelink() からどこかを経由してまたmake_pagelink() へと戻ってくるという、危険な無限ループが存在することになってしまいますが・・・ -- 2009-03-20 (金) 22:16:22
      • いっそ
        	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>Q&A]]
    というルールを作成したのですが2009-03-20 (金) 00:01:42のtoString()の状態でQ&Aの半角&を使える状態を確認しました。
    そこから上記にあるtoString()の修正を試してみたのですが、変わらずzzzzのリンクはabc/aaaでして、&の半角はご指摘の通り使えなくなりました。(全角はOKです)
    キャッシュも正常でしたので、無限ループしているかもしれないのですね、一応エラーは出ておりませんでした。
    さらにその次の修正案を試してみましたところ、return make_pagelink($this->name, , ,$this->page);の行でエラーが発生しました。
    // AutoAlias
    class Link_autoalias extends Link
    の部分ですので、場所は間違えてはないとは思うのですが、もしも違う場所を修正しているといけませんので記載しておきました。
    AutoAliasが正常に使えるのでしたら、半角&などの文字を諦めてもいいかなとは思います。
    • read.inc.php の修正(差分の修正前と後の両方)を試してみましたが、2つと認識はしてくれませんでした。
      AutoAliasや各リダイレクトなどをplusと同じ形にすると上記の問題は発生せずにすんなりいけてしまうものなのでしょうか。 -- こしまえ? 2009-03-20 (金) 23:07:24
  • return make_pagelink の件、上の案を修正しました。(テストできてなかったせいです) -- 2009-03-21 (土) 07:24:00
    • ループの件、make_pagelink() 内で
      		if (count($realpages) === 1) {
      			$realpage = $realpages[0];
      			$link = '[[' . $s_alias . '>' . $realpage . ']]';
      			return make_link($link);
      			}
      		}
      みたいなことをしない限り、発生しないはずなんですが。(この場合、$realpage がページ名の場合またmake_pagelink() に戻ってくる) -- 2009-03-21 (土) 07:24:00
    • read.inc.php へ修正がうまくいかない件、最新のplus のソースでも、dev:PukiWiki/1.4/ちょっと便利に/ページに別名をつける の差分でも基本的には、
      1.ページが存在した場合は、必ずそれを表示する
      2.セーフモードでない場合でInterWiki が送られてきた場合は、それのリダイレクトをトライする
      3.(1. でページがないことはチェック済み)ページ名が送られてきた場合、エイリアス候補のチェック後、各処理をする
      4.1. ~3. に該当しなかった場合、無効なページ名としてエラーメッセージを返す
      という優先順位なので、同じ形にしている限り1. が最優先になります。(bbb と abc/bbb がある場合、bbb を表示) -- 2009-03-21 (土) 07:24:00
      • こちらで簡単に試したのは、上の「エイリアス候補作成を前に持ってくる例」の直後に
        	$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&#x3a; ' . $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&amp;page=' . rawurlencode($link));
        		exit;
        	}
        
        	// 無効なページ名
        	return array(
        		'msg'=>$_title_invalidwn,
        		'body'=>str_replace('$1', htmlspecialchars($page),
        			str_replace('$2', 'WikiName', $_msg_invalidiwn))
        	);
        という感じに続けたもの(今までの形を捨てたもの)なのですが、
        これだとbbb と abc/bbb というページが同時にある場合、永久にbbb を表示できない(一覧表示し続ける)という問題が・・・。強制的にそのページを表示するオプションを追加しないと、この組み方では無理そうです。
        かといってほかの処理方法を思いつかないんですよね・・・ -- 2009-03-21 (土) 07:24:00
  • 2009-03-20 (金) 23:37:55で修正してみました。しかしこれでも特に変化なしで、リンク先は変わらずでした。ループはどうやらしてないようで、とりあえず大丈夫みたいです。
    readの方も試してみたのですが、こちらも変化無しでリンクは代わりませんでした。
    テストしてもらったとのことですので、どちらも変化無しということは自分の方が何かミスがあるんですね。一応他にこれといった改造はしていないのですが、う~ん。
    • readはもし成功したとしてもさらに問題が出るとのことですが、やはり無茶な要望だったのでしょうか。
      オートリンクを有効に使うときは階層化はしないというpukiwikiのスタイルという記事を見て、
      ページ数が多く、階層化とオートリンクを同時に使いたい場合に有効な内容だとは思うのですが。 -- こしまえ? 2009-03-21 (土) 13:20:26
  • ちょっと待ってください。ページ中のリンクの状態は、lib/make_link.php 以外を触っても変わらないはずですよ。(lib/convert_html.php 内部のルールや、ページ内に記述するタイプのプラグインを改変した場合は、別ですが)
    read プラグインは極論すれば、ページを表示するかを判断して、その橋渡しをしているだけなので、ページ中のリンク状態には何の影響もありません。 -- 2009-03-21 (土) 15:04:48
    • 1つ前に挙げたread プラグインの改造法に問題があるのは、私の考えた処理方法や順番に問題がある(オプション追加したら回避はできそう)というだけで、もっといい方法があるかもしれません。 -- 2009-03-21 (土) 15:04:48
    • 無限ループしていないのは、AutoBaseAlias の候補がないときに
      [[ggg>hhh]]
      [[hhh>ggg]]
      
      [[ppp>ppp]]
      というような、ループしそうなAutoAlias を設定してからテストしていないから助かっているだけ、という訳ではないですよね?
      make_pagelink() からmake_link() 経由でmake_pagelink() に返ってきたり、直接make_pagelink() にという隙があると、置き換えをしているので非常に危険です。
      今のソースの形がわからないのでしつこく言っているだけで、バグの見落としなどの問題がなければそれでかまいません。 -- 2009-03-21 (土) 15:04:48
  • 何も変化がないと思っていたんですが、そういうことだったのですか。本名が2つ以上(bbb、abc/bbb)ある場合はそこだけURLがread~になって、どちらのリンクもクリックするとread.inc.phpにいって、そこから一覧がでるものだと思っていました。
    • お手数かけて申し訳ありませんでした。上記の修正を試してみたところ、リンクをクリックしましたら無事選択画面となりました。そしてご指摘の通り、bbbをクリックしても一覧表示が表示されてしまいました。
      これはリダイレクト先のURLと同じなのでおきる現象だとは思うのですが、 -- こしまえ? 2009-03-21 (土) 15:15:56
  • 「今のURLとリダイレクト先のURLとが同じなのでおきる」、そうなんですよね。アレをそのまま生かすのなら、
    候補を呼び出すかを選択するパラメータを追加して分岐するようにするか、
    今までの(無改造状態の)read プラグインをread2.inc.php に改名して、その中のplugin_read_action() をplugin_read2_action() に改名してread2 プラグインへリダイレクトするか、
    ぐらいですからね・・・。 -- 2009-03-21 (土) 15:57:16
  • ループはご指摘のものを試してみました。
    [[ggg>hhh]] (hhhは存在する)
    [[hhh>ggg]] (gggは存在しない)
    [[ppp>ppp]] (pppは存在する)
    とした場合、特にループはおきませんでした。&br: そしてここから存在しないgggというページを作ろうとした時(readを修正前のplusの状態)
    header('Location: ' . get_page_location_uri($realpage));
    この行でエラーが出るので作成できませんでした。他の関係の無いページを新規作成は可能です。
    作成できてしまうと不具合が起こりそうなので、これで良いのかな?と思っています。
    pppが存在しない場合も試してみましたが、こちらもppp?となるだけで、?をクリックしても新規作成できないエラーが出るだけなので、特に問題ないかなと思いました。
    • read2ということは、新しくプラグインを作るみたいな感じになるのですね。
      どちらかというとそちらの方が管理なども楽そうですし、よさそうな感じですね。 -- こしまえ? 2009-03-21 (土) 16:35:47
  • ppp → ppp → ppp → ・・・ と、無限にループしていないので大丈夫そうですね。 -- 2009-03-21 (土) 17:34:10
    • get_page_location_uri() もplus の独自追加関数です。plus のlib/func.php にありますが、これ1つだけでは使えない(ほかにも色々移してこなくちゃいけない)ので、等価なものに書き換えたほうが早いです。
      意味合いとして、
      header('Location: ' . get_page_location_uri($realpage));
      header('Location: ' . get_script_uri() . '?' . rawurlencode($realpage));
      と同じです。 -- 2009-03-21 (土) 17:34:10
    • 「新しくプラグインを作るみたいな感じに~」とはいっても、雛形がすでにPukiWiki のパッケージにあって、ファイル名と関数名を書き換えたら完成ですから、一から作るよりは楽ですよ。
      仮にアップデートするとしても差分を取りやすいでしょうし。他の改造箇所は重大な問題に関しては、PukiWiki とplus の両方の差分を追わないといけないので、大変そうですけどね。 -- 2009-03-21 (土) 17:34:10
  • 上記の差分に修正しましたところ、エラーはなくなりました。他にも同じ箇所がありましたので、そこも修正してpppが存在しない場合のエラーも出なくなりました、ありがとうございます。
    • 本家pukiwikiの無改造read.inc.phpをread2.inc.phpにし、function plugin_read2_actionを書き換えただけなのですが、read2をプラグインフォルダにいれておきました。
      ここからread.inc.phpで// エイリアス候補がある場合(リダイレクトしなかった場合を含む)、一覧表示
      の箇所でread2にリダイレクトさせるようにするということなのでしょうか? -- こしまえ? 2009-03-21 (土) 18:32:31
  • リダイレクトだと一覧を表示する前に、特定の場所に飛ばしてしまうような・・・。
    		$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
  • 試してみましたところ、無事read2を通して表示できました。リダイレクトはreadを通した後に本URL(readで表示しない通常の表示)にリダイレクトするのかなと思っていました、勘違いですみませんです。
    そして色々と試してみました、前提としてaaa,abc/aaa,abc/bbb,def/bbbというページがあったとします。
    aaa ○
    abc/aaa ○
    abc/bbb bbb?となり、?をクリックするとreadに飛んでabc/bbbとdef/bbbの一覧に
    def/bbb 上記と同じ
    という結果となりました。この状態でbbbというページを新規作成しようとし、新規作成フォームでbbbと入力するとreadのabc/bbbとdef/bbbの一覧へとなりました。
    実在するページ(bbb)が無い時は「?」をクリックするとbbbの一覧に行くようですが、できれば上記の状態でもbbbを作成できると良いのですが、仕様上厳しそうですね。
    後になって実在する(bbbを作成)はともかく、実在するページが無い状態だと「?」になってしまうのは、ある意味好ましい状態(複数ある場合は自動でreadに飛ばしてくれる)のですが、これを?ではなく、通常のリンクの形にさえできてしまえばAutoBaseAliasについては大体完了?な気がします。
    • function toString「zzz リンクは作成されましたが、指定したaaaでは無くabc/aaaへリンクに」は現状でどのパターンを試してもやはりabc/aaaへといってしまいます。 -- こしまえ? 2009-03-21 (土) 20:28:41
  • 新規作成フォームということは、newpage プラグインですか?それなら、リダイレクト先をread2 にすれば、オリジナルと同じ動作になると思います。というか、一覧や検索結果やその他もろもろ全部の機能でread を呼んでいた場所を、read2 にしないとダメなのかもしれません。
    cmd=read を省略しているのも含めると結構あるような・・・。名前逆のほうがよかったのかもしれない。(いまさら・・・) -- 2009-03-21 (土) 23:45:50
    • 複数候補があるときは、「// 有効なページ名への編集リンクを追加」の辺りのように編集や他へのリンクを追加できるのですが、1つのときは一覧せずに直接飛んでしまうので、今のままだと確かに厳しいですね。 -- 2009-03-21 (土) 23:45:50
    • abc?abc は前にも紹介した質問箱/4042 を参考にしてください。 -- 2009-03-21 (土) 23:45:50
    • 「zzzz なら指定したaaa なのに、zzz なら指定したaaa にならない」、これがわからないんですよね。
      Link_autoalias::toString() を出るときに1回+make_pagelink() で1回とか、make_pagelink() で2回 変換とかだったら、zzzz の方も指定したaaa になるはずないのに、正常ですし。
      $autoalias の設定で切り捨てされていたら、そもそもzzz がリンクになるわけないし。
      キャッシュのせいでもなさそうだし。コメントの中にルールを書いているわけでもなさそうだし。
      そのおかしくなるリンク、実は[[zzz>aaa]] と書かれているからでもないよな~。(それだと、AutoAliasName に書かれているリンクほとんどが、おかしくなりそうだし) -- 2009-03-21 (土) 23:45:50
  • ああああ、すいません。どうやらzzzは前提が間違えていたようです。
    前提として abc,bbb,abc.aaa,abc/aaa,abc/bbb,xxx,abc/zzz(追記)というページがあったとします。
下記はAutoAliasです
[[google>http&#x3a;//www.google.co.jp/]]
[[zzz>aaa]]
[[zzzz>aaa]]
[[yyy>xxx]]

下記は結果です
zzz リンクは作成されましたが、指定したaaaでは無くabc/aaaへリンクに
zzzz ○

つまり別名で指定した文字が階層下で実在(abc/zzzはありますが、zzzはありません)する場合、その文字をAutoAliasで設定しても、AutoAliasで指定した本名よりAutoBaseAliasの方が優先されてしまう。
という状態なのだと思います、今までこれを表記せずに質問なんてしたりして本当に申し訳ありません。
この違いで何かわかることがありましたら。

  • abc? → abcについてなのですが、実際にページがない場合は通常の「abc?」にし、readに飛ばす時だけ「abc」のリンク状態にできればと思いました。
    といっても分岐させればいいのだと思うのですが、もしかして「リンクがreadで飛ばす」時と「ページが無い状態」を区別させることができない状態なのでしょうか?
    どういう記述で区別させれるか想像がつかなかったので。
  • newpageプラグインの方をread2にしたところ、うまく新規作成できるようになりました。
    しかし実在するページとしてbbbを作成してもページの一覧を更新してしまうので、消去しない限り一覧は出ることがないんですね。
    一覧にbbbが加わり、abc/bbb,def/bbbの3つ表示してくれるのかもと思ったのですが。
    しかしこれも実在するページを作らなければいいだけなので、やはり厳しそうならこのままでいこうと思います。 -- こしまえ? 2009-03-22 (日) 00:35:08
  • zzz がない&候補が複数あるはず(zzz に対してaaa とabc/zzz)というのを期待しているのに、zzz へのリンクにならずに置き換わっているのが謎ですね。
    AutoBaseAlias でzzz に対してabc/aaa というルールは作れないはずですし、候補のリストはAutoAlias → AutoBaseAlias で並んでいるはずですし・・・。
    var_dump(get_autoaliases()); と(スキンの中など)確実に呼ばれる場所に書き込んで、リストを1回確かめてみるほうがいいんだろうか? -- 2009-03-22 (日) 15:51:57
    • 今のmake_pagelink() は
      1.ページ名が空の場合、そのページのアンカーへのリンクに
      2.ページが存在しない場合、候補を呼び出し処理をする
      3.AutoLink が作ったリンクの場合、ページが存在にかかわらず通常リンクになる
      または
      そのページが存在する場合、通常リンクになる
      4.3. に該当しない場合、Dangling link (「abc?」の形)になる
      という順番で処理をしていると思います。
      今問題にしているのは、2. で候補を呼び出したが複数いたのでページ名を置き換えしなかった、というパターンですかね? -- 2009-03-22 (日) 15:51:57
      • これならどうでしょう?
         	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 をリセットしたほうがいいかも)
        ページがなく候補もない時だけ、4. に進むと思います。 -- 2009-03-22 (日) 15:51:57
  • >var_dump(get_autoaliases()); と(スキンの中など)
    とのことですが、スキンに直接zzzなどのリンクを書き込むということでしょうか?
    一応実験として、さらにtest/zzzというページを作成したところ、リンクは指定した実在するaaaでは無く、readプラグインのtest/zzzとabc/zzzの一覧へのリンクとなりました。
    他にも何かしたら試せることがありましたら、自分の知恵でできるかぎりなんでもしたいと思います。
    • 「候補を呼び出したが複数いたのでページ名を置き換えしなかった」、この通りだと思います。
      差分を試しましたところ、形的には完璧なのですが、リンクはreadプラグインに飛ばすから→存在しないページ名にリンクとなってしまいました。
      候補が複数ある場合は通常のリンクの形でreadへ飛ばし、未作成はそのままDangling linkの形ができればと。
      現在は
      		// Dangling link
      		if (PKWK_READONLY) return $s_alias; // No dacorations
      
      		$retval = '<a href="' .
      			$script . '?cmd=read&amp;page=' . $r_page . $r_refer . '">' .
      			$s_alias . '</a>';
      
      		if ($link_compact) {
      			return $retval;
      		} else {
      			return '<span class="noexists">' . $retval . '</span>';
      		}
      となっておりますが、ここに分岐(実在するページは無いがAutoBaseAlias候補が複数ある場合?)などを作れたらと思いました。
      もしくはabc/bbb,def/bbbのAutoBaseAlias候補2つあり、bbbという実在するページが無い状態だと「?」になってしまうのでは無く、AutoBaseAlias候補の2つの場合でもbbb?ではなく、通常のリンクの形でreadへ飛ばすことができれば目的の結果は同じとなりそうです。 -- こしまえ? 2009-03-22 (日) 19:23:26
  • 詳しい使い方はPHP関数:var-dump を見てもらうとして、したい事はget_autoaliases() が何を返してくるのかをブラウザで見たいだけです。
    もし、設定していないルールがリストに紛れ込んでいれば作る過程のどこかがおかしいと判りますし、そうでなければ呼び出して処理をする側にまずい部分がある、という様に原因をある程度は切り分けできるようにはなります。 -- 2009-03-22 (日) 21:50:40
    • 「readプラグインに飛ばすから→存在しないページ名にリンク」について、デフォルトでは「?cmd=read&page=エンコードされたページ名」を「?エンコードされたページ名」に省略可能になっています。(&word= や&refer= など、他のパラメータも渡したい場合は除く)
      つまり、表記の仕方が違うだけで通常リンクもDangling link も、リンク先はread プラグインになるはずなのですが・・・。違うところに飛ばされましたか・・・。 -- 2009-03-22 (日) 21:50:40
  • スキンのどこかに貼り付けたらどれにアクセスしてもvar_dumpの結果だけみれるのかと思ったんですが、ちゃんとスキンの出力して見れる場所に張らないと意味がなかったんですね。
    お手数かけて申し訳ないです。
    先ほどvar_dump(get_autoaliases());を試してみましたところ。
    array(28) { ["zzz"]=> array(1) { [0]=> string(7) "abc/zzz" }
    となりました。
    • readに飛んでほしいところ、どこに飛ばされたかといいますとindex.php?bbbというアドレスに飛ばされました。
      う~ん、これも作成前のページもbbb?みたいにせず大人しく普通のリンクのまま表示させてしまえばよいのでしょうけど、
      やはり存在するページと作成前の区別はつけておきたいとの願望だったのですが、
      こちらが少し妥協すればいいだけですので、ここまで要望や質問などしておいてなんですが、もしもあれでしたらこの件は放置でも。 -- こしまえ? 2009-03-22 (日) 23:15:01
  • ああ、表現をまたミスしたかも。index.php?~ というアドレスにアクセスしても、PukiWiki の内部的にはindex.php?cmd=read&page=~ にアクセスしてきたと判断してread プラグインを呼び出します。
    なので、index.php?bbb とindex.php?cmd=read&page=bbb のどちらであっても、表示される結果は同じになるはずなのですが。
    気に入らないからDangling link で振り分けたいというなら、$isautolink = TRUE; ではなく他とかぶらない変数に値を入れて、それを使って分岐するようにすればいいでしょう。 -- 2009-03-23 (月) 00:50:38
    • 「var_dumpの結果」について、[[zzz>aaa]] のルールは登録したままですよね?なのに
      ["zzz"]=> array(2) { [0]=> string(3) "aaa" [1]=> string(7) "abc/zzz" }
      になりませんか・・・。今度はget_autoaliases_from_aliaspage() の結果を表示してみてください。
      この段階で登録されているのならget_autoaliases() 内の処理内容に、登録されていないのならget_autoaliases_from_aliaspage() 内の処理内容に、問題がありそうだと辺りをつける事ができます。 -- 2009-03-23 (月) 00:50:38
  • get_autoaliases_from_aliaspage()を試してみましたところ、
    array(14) { ["zzz"]=> array(1) { [0]=> string(3) "aaa" }
    となっておりました。
    • 表示がされる結果が一緒とのことでしたが、なぜかページがありませんというエラーが発生していました。
      そこでちょっと原因っぽいことがあったのですが、念のため記述しておきます。
      現在はこの項目、AutoBaseAliasをちゃんと導入する為に、使用していたプラグイン([[RewriteMap>http://www.revulo.com/PukiWiki/Plugin/RewriteMap.html]])を撤去していたのですが、差分を修正し忘れていた箇所が数カ所ありまして、
      それを通常の状態にしたところ言われた通りの動作(URLは違うが表示されるページは同じ)になっていたと思います。
      今まで撤去を忘れていて問題が起きていた可能性もあるかと思い、初期状態でゼロからまたAutoAliasこの質問ページのAutoBaseAliasを順に入れ直しました。
      しかし特に変化が無く、aaa/zzzも変わらずなのでreadの表示問題以外は特に影響が無いみたいでした。
      さらに上記プラグインを全部導入済みならどうなるか試してみたところ、修正前はindex.php?bbbというアドレスになっていたところがbbb.htmlとなりまして、bbb.htmlは実在しませんのでエラーに。
      結局RewriteMapプラグインとは相性が悪いのかもしれません。
      横着しないで使用中のwikiをいじらずに、最初から新しくwikiのテストページを作成し、クリーンなpukiwikiでテストするべきでした。
      またも自分のミスで無駄な説明をさせてしまい、本当に申し訳ありません。 -- こしまえ? 2009-03-23 (月) 01:07:38
  • どうも、PHP関数:array-merge の特性がまずそうです。(配列の中の配列を考慮せずに後のもので上書きする、という動作を忘れかけてました・・・)
    get_autoaliases() 内で使っている場所で、PHP関数:array-merge-recursive を使うように変えてみたらどうなりますか? -- 2009-03-23 (月) 21:54:13
    • RewriteMapプラグイン との相性?」について、説明を流し読みしただけなので勘違いしているかもしれませんが、そのプラグインの動作原理は、
      1. サーバのmod_rewrite の機能を用いて、(html 形式の URL にするの場合)アドレスで示されたファイルが存在しない&ファイル名が.html で終わる、この二つが満たされた場合、index.php?cmd=rewritemap&page=(ベース以降のアドレスから最後の.html を除いたもの) にアドレスを置き換えてリトライする。
      2. rewritemap プラグインが受け取った名前と同じ名前のページがあるか、エイリアスやリダイレクトの定義にその名前と合致するルールがあれば、その処理をする。
      という感じだと思います。「BracketName などのリンク先をrewritemap の形式にするパッチ」を使わないか、rewritemap プラグインが(該当するものがなかったため)エラーメッセージを返す場合に、エラーではなくread へ送るように動作を変えるかすれば、お互いをつぶしあうことはそれなりになら減ると思われます。 -- 2009-03-23 (月) 21:54:13
  • 試してみましたところ
    // 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つが表示」の状態となりました。
    念のため、この状態でvar_dumpを試したところ、get_autoaliasesとfromの両方変化無しでした。
    • RewriteMapプラグインについてですが、エラーが出る場合はreadに飛ばすことができれば、ご説明の通り解決できそうですね。
      とても勉強になります、とりあえずBracketNameの修正のほうを見てみたいと思います。 -- こしまえ? 2009-03-23 (月) 22:18:23
  • 何を基準にして変化なしなのかがわかりませんが、AutoAlias + AutoBaseAlias の現在の状態は、こしまえ さんが目標とする状態になっていますか?もしなっているのなら、基本的には終了ですね。
    話がだいぶ長くなってきたので、他の質問として分けられそうな項目は次の質問として新たに投稿した方がいいですよ。他の方が質問箱の一覧からタイトルで情報を探すときや、検索で必要な情報を探すときに、楽に見つけやすくなるので。(さすがに、タイトルと内容が極端に違うのは避けたいですし、話の流れを追うのも大変になるので) -- 2009-03-24 (火) 00:38:24
  • 変化無しというのは
    ["zzz"]=> array(2) { [0]=> string(3) "aaa" [1]=> string(7) "abc/zzz" }
    array(14) { ["zzz"]=> array(1) { [0]=> string(3) "aaa" }
    となっていたので、この部分は変化無しということでした。
    ほとんど希望通りの動作となりましたので、完了にしたいと思います。
    おっしゃる通り、長くなりましたし、質問内容とは離れたことも聞いてしまいました。
    ここまでつきあってもらい、感謝の言葉もありません。
    解説など本当にありがとうございました。 -- こしまえ? 2009-03-24 (火) 01:13:57


*1 「ページ名がかぶった場合はリンクをクリックした時にユーザーがリンクを選択できる形」を実現している機能
*2 AutoAlias でのみコレを許すのか、それともplus と同じようにWikiName や、BracketName 、AutoLink からでもコレを許すのか
*3 デフォルトならlib/link.php のref とrel のキャッシュを作るところと、lib/make_link.php のAutoAlias のところ
*4 正確には、別名1つに対して本名1つというルールでget_autoaliases() が成り立っているんで、実質そこで決まっているんですが・・・
*5 実際には、[[abc]]でかこっていないのですがリンク作成状態となってます
*6 ルールを改ざんされると、想定外のサイトに飛ばされる可能性がありますが・・・(この場合、ルールを書くページには認証か凍結が必須になる)

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2015-04-24 (金) 17:08:43
Site admin: PukiWiki Development Team

PukiWiki 1.5.2+ © 2001-2019 PukiWiki Development Team. Powered by PHP 5.6.40-0+deb8u2. HTML convert time: 0.563 sec.

OSDN