« 2006年02月 | 過去ログ一覧 | 2006年04月 »

2006-03-01 (Wed)

カーソル位置の…を CSS のみで実装

先日書いた カーソル位置のセルの上端と横端をハイライトする JavaScript を CSS のみで実装しちゃった方が居ました。

残念ながら IE では対応していない等いくつか制限があるようですが、CSS だけでやろうと思うのが凄い。久々に感動した。

両方やっておくと、JavaScript を切ってる Firefox なり Opera の人にも便利になりそうですね。

△トップ | コメント (0) | トラックバック(0)

2006-03-04 (Sat)

次世代のフォーム処理について

だから今後のフォーム回りの設計については、基本的にJavaScriptなしでもフル機能動作するフォーム設計を行った上で、もしもJavaScriptが利用できる場合はより快適に動作する、といった方針で作っていくことを考えていた。

基本的にはonSubmitをフックして、JavaScriptで対応できる処理の場合はJavaScript側で処理を代行した上で、return false;するようなアプローチね。

引用元: いしなお! - 次世代のフォーム処理 (いしなお! より)

同意。JavaScript オフだと動かないウェブサービスなんてうんこうry。

ちなみに自分の場合は、追求はしていないけど現時点でそれなりに自己満足してる方法はあります。

フォーム送信先のページで適当に区切りとなる文字(コメント文とか)を出力しておいて、JavaScript が on の場合は、XMLHttp 通信を使ってその部分だけを取得して元の画面内に描画、そうじゃない場合は普通に画面遷移して描画っていう事をしています。こういう事をしてるっていう話しはあんまり聞かないけど、すごくお手軽な上に操作感も向上したと感じると思ってます。

元々出力するはずだった HTML を切り取ってるだけなので、サーバもクライアントも速度が向上するわけではありませんし、負荷も減るわけではありませんが、サクサク感が違います。あと適度にエフェクトも付けると派手さがアップして素人受けは多分良いです。

具体的にどういう画面で使用しているかと言うと、ウェブ上でデータの編集・削除を行なうようなフォームで使っています。たとえば、会員情報の変更や削除とか。これらは結構導入しやすいです。MM/Memo の投稿の編集画面とかでやっても良いんじゃないかって気がします。

まぁ、これだけだと次世代と呼ぶのは恥ずかしすぎるので、だれかお手軽でカッコイイ方法があったら教えて欲しい。

ちなみに、送信先の内容によっては 悪いAjaxの使い方 って言われちゃうので気をつけないといけませんけど。

ていうか、サーバーとクライアントでテンプレートを共有したい場合 てのは結構良さげだと思うんですけど、駄目なんですか?上で書いた方法は、かなりこれに近いんですが。いずれはそういう形にしたいとも思ってましたし。

△トップ | コメント (2) | トラックバック(0)

2006-03-05 (Sun)

Trac のアクセス制御

詳しい事は、trac 自体の wiki:TracPermissions に書いてありますが、デフォルトになってる

anonymous TICKET_MODIFY

は削除して、

anonymous  TICKET_APPEND

を追加した方が良いと思う。

TICKET_MODIFY だと、チケットの属性値(TypeとかComponentとか)を変更出来るのだが、anonymous な人が属性を変える必要も無いでしょう。TICKET_APPEND なら、コメントが付けられるので、権限の無い人はこのくらいで良いと思う。

でも配布サイトは、TICKET_MODIFY なんだよなぁ、あんまこういう事って気にならんのかなぁ。

△トップ | コメント (0) | トラックバック(0)

2006-03-07 (Tue)

はてな行ってきた

Welcome?  ほんと言うと hatena.ne.jp の事では無い


玄関まで。

△トップ | コメント (0) | トラックバック(0)

2006-03-08 (Wed)

Trac からリポジトリ内全文検索やってみた

リポジトリの全文検索 with HyperEstraier プラグイン ver 0.1 を試してみた。

この WeekBuildのHACK日記 は他にも色々と Trac のハックをされているので、Trac フリークにはお勧め。ページランクアップにも貢献しておきたい :-)

さて本題。HyperEstraier 検索プラグインは、主に Windows ユーザ向けに説明されている感じなので、せっかくだから Unix 系でもやってみましたよっていうご紹介。

環境は Trac0.9.4 on Debian/Sarge。まず最初に必要なもののインストールから。

HyperEstraier は大昔にソースから入れたので省略。Debian Etch だとすでにパッケージ化されていたはずなので、apt-get で入ると思うけどそうじゃない人はソースから make install して下さい。

次に、この EGG 系の拡張機能を利用するためには setuptools というのが必要らしいのでインストール、なんだけど、パッケージ化されている setuptools は 古くて動かない ので、自前でインストール。これは簡単。

$ wget http://peak.telecommunity.com/dist/ez_setup.py
$ python ez_setup.py

んで、さっきのサイトから searchhyperestraier-plugin を落としてきて、展開したディレクトリ内に SearchRepositoryWithHyperEstraier-0.1-py2.3.egg というファイルがあるので、こいつを trac のデータディレクトリ内の plugins というディレクトリに配置。

そこまで出来たら、estraier の転置インデックスの作成。

まず適当なディレクトリにリポジトリをチェックアウトしておきます。例では /home/data/est/ 内に色々データを置いておく事に。

$ cd /home/data/est/
$ svn co /path/to/repos/trunk repos

次に、以下のようなバッチファイルを用意して転置インデックスを作成。もともと紹介されている方法では、リポジトリを毎回エクスポートしていて無駄に感じたので、svn update をして更新するように変更した。

#! /bin/bash

DIR=/home/data/est/repos
IDX=/home/data/est/idx

PATH=/usr/bin:/usr/local/bin

svn update $DIR
cd $DIR
svn ls -R $DIR | estcmd gather -cl -ft -sd $IDX -

バッチを実行して転置インデックスが出来あがったら、ちゃんと検索出来るかどうかを確認しておく。

estcmd search -vx -sf /home/data/est/idx hoge

みたいな感じで。ホントに hoge って入れても多分何も出てこないから注意だよ!うまくいくようなら、crontab に登録しておいて適当な間隔で実行するように設定しておく。

後は conf/trac.ini を設定して準備終わり。

[searchhyperestraier]
index_path = /home/data/est/idx
replace_left = /home/data/est/repos
url_left = /trunk
estcmd_encode = euc-jp
estcmd_arg = search -vx -sf -ic euc-jp

locale が EUC-JP の場合を念頭に入れて、estcmd_encode と estcmd_arg をそれぞれ euc-jp に指定しています。多くの場合はこれで平気でしょうけど、自分の locale にあわせないと日本語での検索は出来ないはず。

最後に Apache を再起動して検索メニューでリポジトリってのが出てきたら万事OK。

あとはバッチファイルの内容をもちっと修正したい所。テストめんどいので今日はここまで。

  • gather だけじゃなくって purge や optimize もした方が良いと思う
  • update されたときだけ、estcmd を実行した方が環境にヤサシイ

ちなみに、svn ls -R はちょっとだけ重たいので、嫌だったら find $DIR -name .svn -prune -o -print | estcmd みたいにしてもほぼ同じ結果を得られる。svn ls -R はどちらかというと、Windows ユーザを意識して書いてみた。Windows でパイプ処理が動くかどうかは知らないんだけど。

△トップ | コメント (2) | トラックバック(0)

2006-03-12 (Sun)

prototype.js の Form.Element.Serializers をハックしてみたよ

思いっきり乗り遅れ感抜群って感じなのですけど、昨日から prototype.js を使った JavaScript のコーディングをやり始めました。

moo.fx とか、Yahoo のライブラリ とか色々見てまわったんだけど、結局 prototype.js + script.aculo.us が一番お手軽高機能っぽく感じたのでこれを使う事にしました。

そんでもって、今まで自前でやっていた処理が組み込みの関数で出来るんだ、便利だなスゲェなって思って見ていたんだけど、Form.serialize の機能に不満点がある事が判明。実際自分もここでは苦労したんだけど、同じ所がおろそかになっていました。

Form.serialize は、フォームのフィールド名と値をリストにして返す処理をしてくれて、Ajax とかでフォームの内容を送信する場合に便利なのですが、SUBMIT ボタンが複数ある場合に期待した通りに動作してくれないようです。

普通はクリックした SUBMIT ボタン以外の情報は全く送信されない*1のですが、Form.serialize は全ての SUBMIT ボタンの情報を返してきます。

実際にこれで何が困るのかって言うと、クリックした SUBMIT ボタンの内容で処理を分岐したりしている場合に、クリックしていないボタンの情報が送られて来ると分岐処理がうまくいかなくて期待した通りに動作しなくなってしまいます。

対処方法はないかと検索して、Multiple AJAX submit buttons in a Rails form とか書いてある記事を発見しましたが、何やらちょっと強引に対処しているような感じで明解な解決方法はないようです。

というわけで、prototype.js の後に読み込ませるだけで「クリックした SUBMIT ボタンの情報だけを送信するように Form.serialize の処理を上書きする」ようなコードを書いてみました。

実は一点解決出来ない問題があって、ウィンドウのロード後にフォームオブジェクトを動的に生成した場合、そこで生成した SUBMIT ボタンのクリックを検出する事が出来ません。なので動的生成を行なった場合は、毎回 Form.SubmitFlagger.initialize() を呼び出さないと期待通りに動作しません。ていうか、むしろ initialize してくれないと SUBMIT の情報が誤って送信されるようになっちゃいます。

こんなに一生懸命文章も書いたっていうのに、正直不便になってます。「ハックしてみたよ」じゃねーよって感じ。

タイマーを使って監視すればうまく動くでしょうが、それは綺麗なやり方じゃないから出来ればやりたくありません。だから、誰かもっとうまいやり方を考えてって事なの!なんつーか、もっと根本的にクリックしたかどうかを判定する楽な方法は無いんでしょうかねえ。

03.13 09:29 追記: 4行目の if を書き換えて、動的生成を行なった場合に限っては従来通りの動作をするようにしました。これで「不便になった」って言う状況は避けられたかと。

03.13 16:50 追記2: IE で動いてなかったので、func の処理を修正した。ついでに MacSafari でも動作検証。

var __oginput = Form.Element.Serializers.input;

Form.Element.Serializers.input = function(element) {
   if(element.type.toLowerCase() == 'submit' && element._lclick)
      return this.submit(element);
   return __oginput(element);
}


Form.Element.Serializers.submit = function(element) {
   if(Form.SubmitFlagger.getValue() == element._lclick)
      return [element.name, element.value];
}

Form.SubmitFlagger = {
   initialize: function() {
      var func   = function(val) {
         return function() { Form.SubmitFlagger.setValue(val); };
      }
      var inputs = document.body.getElementsByTagName('input');
      for (var i = 0; i < inputs.length; i++) {
         var input = inputs[i];
         if (input.type.toLowerCase() == 'submit') {
            input._lclick = i;
            Event.observe(input, 'click', func(i), false);
         }
      }
   },

   setValue: function(val) {
      return this.button = val;
   },

   getValue: function() {
      return this.button;
   }
}

Event.observe(window, 'load', Form.SubmitFlagger.initialize, false);
  • *1: 普通って書いたけど、RFS とかそういうので定義されているのかまでは調べてなくて適当に書いてますけど

△トップ | コメント (0) | トラックバック(0)

2006-03-20 (Mon)

自作 Trac マクロ - MyTitleIndex

Trac の TitleIndex のページに出るページ一覧なんだけど、Trac のインストールやヘルプに関するページが多いので、ちょっと邪魔くさいっていうか見通しが悪いです。

なので、デフォルトのページを除いたリストを生成する MyTitleIndex というマクロを作って、[[TitleIndex]] の替わりにこっちを使うようにしました。あとついでに、ページ名の横にページのヘッドライン(タイトル?)も表示される機能も入ってます。

このファイルを wiki-macros ディレクトリに放りこんでから wiki ページで [[MyTitleIndex]] とかやって呼び出すと、デフォルトのページを除いたページの一覧が表示されます。

他にも表示を抑制したいページがあったら、行頭にある wiki_pages の配列にページ名を追加するだけで表示されなくなります。特に インタアクトの trac-ja を使っている方は、TracJa と TracTermsJa は追加しておいた方が良いでしょう。

コードは SubWiki を参考にしたといいますか、インスパイヤというか、ほとんどそのままパクリでごめんなさい。wiki_pages の配列は、checkwiki.py から持って来ました。

MacroBazaar は勝手に登録して良いのだろうか、後で調べよう。 → ML に送ればイイみたい → 送ったけど届かないな…?amavis にはじかれてる??

△トップ | コメント (0) | トラックバック(1)

 
Copyright (C) Kyosuke Takayama, Some rights reserved.