実装したものと実装のための情報。
このWikiを洗練させるための試作。
http://x.pmint.name/


プロトタイピング05 Edit

どこから実装するか Edit


MV*のモデル層の責務分担と構造(依存関係と多重度)から。でもXのモデルはページページ/要素ぐらい。

その後は自由に、思いついた順に。

実現可能かはいつでもサンプルを作成して確認。

検索/フォーマットは検索Elementに含める。
Prototype.png

プロトタイピング/05 Edit

やること Edit

プロトタイプ05+04+03 Edit


05の次。

概要 Edit

abstract.svg

docs.google.com

とりあえず利用者はUserクラスで、権限は固定値で。

fw/Web Edit

MVC.svg

docs.google.com

資料 Edit

やること Edit

クラス構成 Edit

p05.svg

multi-gram→ページ名 Edit


各クラスのプラグインは書かない。

あとはVisitorをElement周辺に付け足すだけでクラスが揃う。

プレビュー Edit

資料 Edit

フレームワーク Edit


:t/Webフレームワーク部分と、その上の:t/Wikiフレームワーク部分。

ページ/:t/要素が動く環境を作る。

ユーザーからのリクエストを対応する要素に伝えて、その結果をレスポンスに変える。

権限 Edit


権限設定示。

下位展開 Edit

自動リンク Edit


リンク規則、danglingリンク規則、ページ名(フルパス)→内部名

:t/汎用記法:t/埋め込み機能を呼び出して権限情報を示。

ページとその属性名を全て:t/URIで指定・参照・ページ上にレンダリング。

下位展開 Edit


:t/下位展開は複数のページをまとめて見せる機能

ページ名…Pagename

対象になるページ:t/順不同:t/名前での下位に位置するページ

自動リンク下位展開を考慮。一部を#化してリンク

自動リンク規則…PlainsAutoLink追加→HTML化のときに他のPlains系と異なる出力になるので不可。Notations系として実装するならフレームワークにPatternを提供しないと。

ページ作成記法ページ編集記法…パラメーターはデフォルト値。作成は状況により編集に、編集は状況により追記になる。

自動リンク規則は相対パス→絶対パス変換に一手間加えたもの。

ページ間の:t/リンク下位展開に対応する必要がある。

まとめられたページ:t/見出しとして示されるので、リンク先もそこへつなげなければならない。

プレビュータイムマシンとサブセット Edit


プレビューWiki

同じ見解を見てるみんなの履歴

Wiki(-name)の補完ルールを変える。Pagenameクラスで対応すればいいだけ。

リクエスト-レスポンス間にWiki(-name)は一定。

存在しないページはデフォルトWikiから探す。デフォルトWikiにも存在しないなら、プレビュー用Wikiのページが存在しないときの処理。

ページごとに:t/権限判定と:t/代表の適用が必要。

プレビューモード Edit


:t/プレビューモードは:t/名前の補完ルールに細工をすることで実現。

タイムマシンモードも同じ発想。

タイムマシンWiki

自分が見てきた履歴

Revisionの補完ルールを変える。Pagenameクラスで対応すればいいだけ。

リクエスト-レスポンス間にRevisionは一定。

存在しないページは存在しないものとする。

まだ投稿していないページ:t/セッションに一時保存。

セッションの実体は特殊な:t/ページ。一時的ではあるが:t/永続化することになる。

ほか Edit

紹介 Edit


相変わらずページの保存が出来ないバージョン

サンプルデータとして http://wiki.pmint.name/ のページインポートしてみた。

実装したこと Edit

  • これまでのプロトタイプでやり残していること

そのほか Edit

  • multi-gram
    自動リンク処理で行なっていた”bi-gramを使ったページ名探索”。連続する2文字をインデックス化していたが、数字列では1つのキーに集まり過ぎ、漢字を使う単語では分散し過ぎだったので、文字種により0文字から3文字を使うよう変更。

プラグイン Edit

実装方法 Edit


名称「PageElement」または「Element」。「Notation」は記法なのでRegexを使って定義するもの。「プラグイン」は実装の仕方なので使わない。
  • プレビューWiki
    [Pagename、Wikiを明示指定]

    Previewモード

    指定されたWikiにページが無ければ、デフォルトWikiのページを使う。

    デフォルトWikiにも無ければ、指定されたWikiでページが存在しない処理。
  • タイムマシンWiki
    [Pagename、の補完方法で](プレビューとは実装方法が違う)

    Back way to ... モード

    日時指定→の補完時に番号に置き換え

    日時指定用のUI: の中から選択、あらかじめページ名見解が指定されていないと

    ページ(Entry)が無ければ、普通にページが存在しないときの処理。

プラグイン側で定義できるものはクラス定義で Edit

  • NotationRegex)のデフォルトはプラグイン内部で定義。Wiki上で再定義されていればそれを使うように。
  • 連結するか否か(bool)
  • Notationクラス名
    • -------------------------------------
  • Notation→ElementでPukiWikiのようにRegex1回にしないのはネストを可能にするため。Notationのネストを内側から探すのも同じNotationをネスト可能にするため。

「C#に依存するコードが増えてきましたが」

そのうちやること Edit

自動リンク Edit

データ変換 Edit


テキスト→オブジェクト→HTML

オブジェクト→永続オブジェクト

もしWikiNotationプラグインをまったく使えないWikiEngineを作ったら…

テキストを記録するだけ。

ファイル名とテキストを与えると記録、ファイル名のみならテキストを出力。

これにプラグイン独自のデータと処理を加えて、プラグインごとに違うHTML出力ができるようにする。

中心はプラグインを作るためのAPI

アカウント Edit


利用者

派閥 Edit


派閥[?]

プラグインは既存クラスの「プラグイン Edit

  • Usecaseプラグイン
    Plugin/Usecaseを実装。

    SubUsecaseも使うならクラス名自由。

    フレームワークは関わらないので。リクエストの任意のパラメーターを使っていい。
  • PageElementプラグイン
    Plugin/PageElementを実装。

継承をするよりもコードテンプレート

クラス Edit


→クラス[?]

X

クラス名は…

View::ユースケース名::リクエスト名、Control::ユースケース
  • PageElements
    記法別クラスの上位クラス。

    記法別クラス(Notations)はWikiTextを読んで自身が理解できる記法だけオブジェクト化する。

    WikiTextの先頭からではなく、記法別にオブジェクト化。

Edit


クラス図

クラス図

フレームワーク間の関係 Edit

HTMLを要求するのはフレームワーク/Webアプリケーションのほう。
WebアプリケーションはWikiEngineを3回呼ぶ。

  1. エントリーポイント
  2. フレームワーク/Webアプリケーション
    Xオブジェクトを生成。
  3. フレームワーク/WikiEngine
    Xオブジェクトを作る(だけ)。
  4. フレームワーク/Webアプリケーション
    Xオブジェクトにリクエストを伝える(そのまま渡すのではなく、変数の形で)
  5. フレームワーク/WikiEngine
    自身の状態を変化させる。状態は永続化する。
  6. フレームワーク/Webアプリケーション
    XにHTMLを要求。
  7. フレームワーク/WikiEngine
    HTMLを生成。
  8. フレームワーク/Webアプリケーション
    HTMLにヘッダーを付けてWebページ化。

Wiki、Entry、Side、Revision Edit

  • Entry(項目)
  • Side(見解
  • Revision(

いずれもPageクラスのインスタンス名。

ただし、実体があるのはRevisionだけ。その名を変えたのがEntry、Side。
  • -------

排他制御 Edit


永続化クラスを排他制御不要な方式に。

WikiはEntryの構造体。

ルートページから始まるツリー構造。

モデル系クラスでは自分で自身を書き換える。他のクラスを扱うのはPageFactoryくらい。

各Entryもそれぞれツリー構造。

つまりツリーの要素からまたツリーが始まる2段ツリー構造。

エラーレベル Edit

  • 利用者向け情報 Info
    不正なリクエストなど。ページメッセージ欄に出力。

    X/Error/Info[?]
  • 警告 Warning
    デバッグ用ログ出力と管理者グループ宛メールに出力。

    処理続行。

    X/Error/Warning[?]
  • 致命的エラー Fatal
    処理中断。

    開発時のアサーション違反はエラー、運用中は警告だけ。

    X/Error/Fatal[?]

実装からTips作成 Edit


実装からTips作成、よりよいコードのヒント集め。

実装以外にも、アイデア、方式、UIなどでも。

排他制御 Edit


更新コマンドのキューイング。

キューと要素の関係。

キュー→ファイル(名前順)

要素→永続化されたCommandオブジェクト。

ファイルロックは…PageFactoryが永続化されたオブジェクトを復帰/保存するときと、オブジェクトが自身の関連ファイル(他のオブジェクトの所有物でないファイル)を操作するときくらい。

モデル系クラスでは自分で自身を書き換える。他のクラスを扱うのはPageFactoryくらい。

仕様の分け方 Edit


フレームワークは空気。ページが本体でユーザーがそれを利用できるようにするのがフレームワークの役目。

UIの内訳

1. 読みUI

ページ/履歴含む。

2. 書きUI

エディターなども。

3. 探しUI

検索の他に関連情報やおすすめの類も。

4. 組み立てUI

管理とWiki構築。テンプレートデータコンテキストなどページ/要素を使ったプログラミング部分。

フレームワーク/Webアプリケーション

Componentの使い方 Edit

  • WikiEngine(の代表的なクラス)を1つのComponent(MVCセット)にする
    WikiEngine内部ではクラス間はWikiNotationで関連するので。似ているけど別の仕組み。

    UsecaseやRequest、Query(検索/クエリーではない)もWikiEngineの一部。Componentの<<control>>や<<model>>部分になる。

    WikiEngineの全クラスをComponentにしなくていい。フレームワーク/Webアプリケーションと関わりのあるクラスだけComponentを継承
  • サイトのグローバルナビを1つのComponentにする

ASP.NETを使うなら Edit


ViewとControllerはASP.NET MVCのもの。

非ASP.NET MVC。Wiki - View(.aspx) - Controller。Viewはマスターページのようなものを1つだけ。

プラグイン無し。ControllerでReadなどを実装。というかControllerがプラグインのようなもの。

フレームワーク/WebアプリケーションはASP.NETと競合するので後回し。

フレームワーク/WikiEngine以上を作る。

実装からTips作成 Edit


実装からTips作成、よりよいコードのヒント集め。

実装以外にも、アイデア、方式、UIなどでも。

PageElement系クラス Edit

  • Wikitext
    処理前の文字列状態。

    stringをPageElementとして扱えるようにするクラス。stringからPageElementツリーを作るクラス。 @done
  • Document
    1ページに1つだけ。PageElementツリーのルート要素。
  • Notation
    • Nestable系 @done
      中に他のPageElementを含むことができる。 @done
  • Autolink
    自動リンク。Plaintextを含む。
  • Plain系
    Plaintextを末端とするネスト構造。Plain系のなにか→Plain系のなにか→Plaintext。

    Plaintextは別。PageElements構造の末端。

ページの設計 Edit

物理:
	- 領域
		テキストファイルを複数組み合わせて1ページ
		保存しなければならないのは投稿されたままのデータ
		- 
			- 属性領域
			- 本文
		- 裏
			- 属性領域
		- 書き込みキュー
			- 1トランザクションのなかでキューをページに反映
			- 最新版
				キューを全て反映したページ
			- 現在
				古いかも?参照用
			- キューの内容は新しいページそのもの
				差分ではなく単体で新しいページになれる。処理の単純化のため。
				反映時は全面書き換え。
──────────────────
属性:
	ページ属性はただNotationを書くだけ。参照時に内容と統合されて1つのelement構造になる。書くところが分かれているだけ。
	- 裏
	- 内部名
	- 凍結
		凍結してるか?はページ/属性
		編集不可能→編集権限を無視してどんな場合も権限なしと判断。
		凍結解除してから編集、再凍結までを一度に行うことで編集可能に見せることはできる。
		編集ビュー凍結されていても閲覧権限で見られる。
	- 不特定多数には非公開属性=特定者にのみ公開属性
		公開範囲別に複数の属性になる?
	- 隠し属性ページ名が明示されたときに見える。
	- 古い自動生成ページを自動更新
	- 自動更新間隔。elementが更新間隔を持つ。更新はページごとなので、ページ内で最も短い間隔で自動更新。自動生成ページだけでなく一般化。
		ページ属性
	- 基本がリンク埋め込みか。という属性
	- 属性値を書く欄。ほかにページ名の接頭辞も属性値の一部。
─────────────────────
内容:
	- 見出し始まり、無ければ自動で作る
	- ページの分割、統合、入れ替え支援
	- バックリンク
	- ウォッチリスト 
	- Web標準
	- 更新日時一覧には編集対象ページ編集対象としてパラメーターになったページ)と、実際に更新されたページの両方を載せる。

できること:
	- 自分宛のクエリーを読める
	- 自分宛のクエリーはHTML出力で作る
	- 添付ファイルもページ
	- HTMLテンプレートページに書く
	- データベースでもある。elementクラス別のデータベースでもある。
	- サイトのアクセスログでもある。ページに記録
	- クリップボードでもある。
	- 多階層ビュー埋め込みのネスト。html1ページヘッダーやシステムメッセージ領域など、複数層の埋め込みでできている。
	- 存在しないページはない
	- 更新できるのは自身だけ。遅延書き込みと前バージョン参照
	- DOMアクセス

名前で3層組み合わせ:
	内部名示名
	項目→ディレクトリ、見解→ディレクトリ、→ファイル
	内部名を使って
	見解ページの応用。
	- 代表
		ワイルドカードを使った一覧から1つ選ぶ仕組み。
	- ワイルドカードで一覧
		ワイルドカードを使った不完全な指定、で、代表を要求しない
		- 項目指定なし、つまり何にもなしのリスト要求
ページ一覧
			代表要求するとルート(FrontPage)
		- 見解指定なしのリスト要求
			見解一覧
			投稿できないので、一覧は示だけ。
			代表要求すると有力見解投票
		- 履歴指定なしのリスト要求
			リスト
			投稿できないので、履歴一覧示だけ。
			代表要求すると最新版
履歴だけ組み合わせ):
	履歴はモデルに含めない。履歴はワイルドカードを使って検索した一覧。
	- 2履歴間の差分
	- 最新の差分閲覧ビューでも強調
		クライアント側で
	- 編集履歴差分
		異なる見解最新版比較(差分示)も?
		通常の差分は同項目・同見解・異間のもの。
下位:
	- 属性継承
		下位展開と関係ある?
	- 属性継承下位ページ
	- 下位展開(閲覧時/編集時)
		下位ページ展開
		- 下位ページの更新は上位の更新日時を変えない。更新日時一覧に上位ページ名も載せる。それで同じ効果。
投票:
	見解投票
─────────────────────
Archive:
	- 複数のビュー。elementクラスごとに分ける・分けない、どれとどれが同じかなどいろいろ。 @done @project(できること)
	履歴: @done @project(物理 / 履歴 @done)
	Merge可能かどうかをインターフェイスで。: @project(Merge可能かどうかをインターフェイスで。) @done
		インスタンス生成せずに呼び出すメソッドはインターフェイス化できない。

プロトタイピング/ Edit