実装のための情報。

実装したものと実装のための情報。

このWikiを洗練させるための試作。

http://x.pmint.name/

プロトタイピング Edit

どこから実装するか Edit


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

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

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

あとで

変換 Edit


PageによるWikitext→HTML変換
  • Wikitextのオブジェクト化
  • Elementから(HTMLなどの)別形式を得る
    HTMLならrender()というメソッド。

プロトタイピング/05 Edit

やること Edit

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


05の次。

概要 Edit

abstract.svg

docs.google.com

変換は多段階で。
  1. Wikitext->統一記法
    記法の優先度順に検出。
  2. 統一記法→PluginNotationElement
    インスタンス化前に記法の連結を行うための段階。

    連結の実態はパラメーターの連結。ここでコンストラクターに渡すパラメーターが決定する。記法はネスト可能なので構造化しないとパラメーターの終端が分からない。
  3. PluginNotationElement→PageElement
    PageElementはデータアクセスに必要。
  4. PageElement→HTML

プラグイン Edit

fw/Web Edit

MVC.svg

docs.google.com

名称「PageElement」または「Element」。「Notation」は記法なのでRegexを使って定義するもの。「プラグイン」は実装の仕方なので使わない。

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

クラス構成 Edit

p05.svg

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

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

データアクセス Edit


ページ内のテーブル記法の内容を配列かList(Of 配列)×配列かList(List (Of String))×List(Of String)に。

リスト(ol、ul)はList(Of String)に。

LINQでSQLのような扱い方が出来る。

fw/WebApp → フレームワーク/UserAgent

資料 Edit

フレームワーク Edit


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

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

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

権限 Edit


権限設定示。

ページに問い合わせ。欲しい別にAPI用意。
Page.getDictionaryData(notationName)

ページは自身の中に要求されたのデータ(Dictionaryなら定義リスト記法)があれば返す。なければnull。

NotationNameは定義リスト記法に書かれている名前。名前を指定しない場合は同じのデータをすべて1つにまとめて返す。

:t/権限は「錠」と「鍵」の2種類。

:t/属性に書く。

下位展開 Edit


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

プラグインは既存クラスのプラグインとして作成。

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

プレビューモード Edit


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

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

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

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

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

プレビュー中も:t/下位展開はある。

クラス Edit


→クラス[?]

紹介 Edit


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

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

実装したこと Edit

そのほか Edit

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

実装方法 Edit


クラス名は…

View::ユースケース名::リクエスト名、Control::ユースケース

Edit


クラス図

http://dl.dropbox.com/u/2267619/wiki/wiki/%E3%82%AF%E3%83%A9%E3%82%B9%E5%9B%B3%20%E3%83%97%E3%83%AD%E3%83%88%E3%82%BF%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B003%20Web%E3%82%A2%E3%83%97%E3%83%AA%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF%E9%83%A8%E5%88%86.png
  • プレビューWiki
    [Pagename、Wikiを明示指定]

    Previewモード

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

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

    Back way to ... モード

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

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

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

クラス図

http://dl.dropbox.com/u/2267619/wiki/wiki/%E3%82%AF%E3%83%A9%E3%82%B9%E5%9B%B3%20%E3%83%97%E3%83%AD%E3%83%88%E3%82%BF%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B003%20X.png
  • -------------------------------------
  • Notation→ElementでPukiWikiのようにRegex1回にしないのはネストを可能にするため。Notationのネストを内側から探すのも同じNotationをネスト可能にするため。

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

そのうちやること Edit

自動リンク Edit

アカウント 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構築。テンプレートデータコンテキストなどページ/要素を使ったプログラミング部分。

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などでも。

Xが呼ばれるまで Edit

  1. エントリーポイント
    (毎回最初に実行されるコード)
  2. Usecase
  3. 指定されたUsecase配下の指定されたRequest
  4. (Requestによる)X呼び出し

PageElement系クラス Edit


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

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

    Plaintextは別。PageElements構造の末端。

プラグインの中にはUsecaseを提供するものも。

ページに埋め込むWikiNotationではなくViewを返す。

X自体がデフォルトのプラグインから呼ばれるようなもの。

ページの設計 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