IIS のurls rewrite を使ってmodxのfriendly url を有効にする。

たとえIISサーバーを使っていてもHelicon Ape というツールをIISに組み込めば、modxについてくる.htaccess をそのまま使っのfriendly url を活用することはできているわけだが、今回はIISのURL rewrite module (IIS 7 の場合は別途ダウンロードで組み込む)を使って同じことをやってみた。

IISのGUIでルールを作る作業になるが、.htaccess の記述を参考にしてやってみたら動くようになった。

modx に付属する.htfile でfurl に関連するところは 以下の部分と思われる

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

これを解釈すると
条件として、要求されているファイル名がファイルとして存在しない、かつ
フォルダーとしても存在しない場合、それはつまり動的に生成されるHTMLページなので、
以下の書き換えルールを適用する。
書き換えルール: 渡された文字列$1を以下のパターンにして加工する
“index.php?q=$1”
さらに 後ろにクエリーがついている場合はそのまま渡し、 下流の処理を行わない。

IISのGUI上のRuleでは これを Inbound rule として追加するが、その内容は以下のごとくなる。

Matches Pattern, “Regular expression”
“^(.*\.html)$” <= RewriteRule の最初の部分*1 Conditions : "Matches All" {REQUEST_FILENAME} "file does not exist"  {REQUEST_FILENAME} "Directory does not exist" Action type "rewrite" index.php?q={R:1} <= RewriteRule index.php?q=$1 に匹敵 Append ques : yes <= [QSA] に匹敵 Stop Processing: yes <= [L] に匹敵 当たり前ながら、同じ条件を記述しているので、それほど迷わずにできた。 はまりそうになったところはRegular Expression の部分で.htmlを明示している部分。これをやらないとloopしてしまう。 ほかのところの条件付けでもっと綺麗に記述できるかもしれない。 とりあえず、これでOK

subfolder がアクセスできない? IIS

Modxで運用するサイトであるサブフォルダーだけアクセスできない。ManagerからはFile Treeで見ることができるのだが、フォルダーの中のイメージファイルの画像をレンダリングしない。 フロントエンドから見ると、イメージファイルの部分でサーバーエラーになっているようだ。

web.configでエラー出力をONにしてみると、エラー500で以下を表示した。

Configuration Error

Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.

Parser Error Message: It is an error to use a section registered as allowDefinition=’MachineToApplication’ beyond application level.  This error can be caused by a virtual directory not being configured as an application in IIS.

Source Error:

 

Line 36:             に、ASP.NET で使用されるセキュリティ認証モードの構成
Line 37:             を有効にします。-->
Line 38: 		<authentication mode="Windows"/>
Line 39: 		<!--
Line 40:             <customErrors> セクションは、要求の実行中にハンドル


さて、これをどう解釈すればよいのだろう?とくよくよ考えるよりは、グーぐる検索をするのが一番で、この記述に行き当たった。

要約するとこういうことだ。IISサーバーで

 It is an error to use a section registered as allowDefinition=’MachineToApplication’ beyond application level.” というエラー表示が出る理由には二つある。

ひとつはアプリケーションをちゃんとバーチャルダイレクトリとして設定していないこと。 これは設定を見直せばよい。

もうひとつは、サブフォルダーにweb.configがルートのweb.configとバッティングするための不具合、

で、今回の場合、サブフォルダのファイルがアクセスできない、ということで、後者だと考え探したらやはりsubfolderに入っていたweb.configがルートのWebFoldeを発見。 考えてみればあたりまえで、このサブフォルダー、以前のテストでスタティックなサイトをやはりIISで運営していたのをmodxでダイナミックなサイトにしようとそのままコピーしていたのだ、から当然web.configもコピーしてしまっていた、というわけだった。

解決策としては、このサブフォルダーのweb.configをバッサリ削除。

 

たくもう。
後記:サブフォルダーにweb.configが存在すること自体、ありうる話(フォルダーごとに書き換えのルールを変えるなど。たとえばOutboundのurl情報からサブフォルダー情報を取り除く) なのでサイトの設定によっては必要なのだが、IISのGUIを使っていれば、このマネージメントはちゃんとなされて調和のとれたweb.configが作成される。
 

ModX cloud

Modx cloud というのをMODXのサイトで盛んに宣伝していたのは知っていたのだが、前回フォーラムにアクセスした際、「タダでアカウントをゲット」みたいなティッカーが表示され、それなら登録だけでも、とMODXCloud.comに登録してみれば、 Dev Siteを一本無料2本無料で使えることが分かったので、早速sandbox サイトを作ってみた。

これは便利だ。サーバーの構築を気にせず、簡単にサイトをリセットしたり、バージョンアップができるようだ。 スニペットやプラグイン、新しいアイデアを試してみたいときに気軽にアクセスしてイロイロ無茶やれそうな場所ができた。

MODXというのはコアを開発している人が基本的に二人なので、開発が細い。 その分、コニュニティで協力してやらなければならないのだろうが、MODXCLOUDのプロバージョンは他のプロバイダーよりも高めの料金設定なので、Financial なサポートをするのも 覚悟がいる。 バージョンアップの節目節目にdonationをするのが今の自分にできることだ。

modx Snippet を改良したときのメンテ法

昔に作ったmySnippet というスニペットがあるとする。 そしてそれを既にサイトのい何か所にも使っているような場合。

改良バージョンでmySnippet2というコードを作って、置き換えようとしたときに、全てのリソースのレファレンスを書き換える手間を省くために、mySnippetを以下の2行に書き換えて、mySnippetを呼んだときには実はmySnippet2を実行するようにしてしまう。


runSnippet('mysnippet2',$scriptProperties);
return $output

きも:modX のrunSnippetというAPIを呼び出して、パラメーターアレイには$scriptProperties というmodxのシステムアレイ変数を使えばmySnippetのプロパティセット及びタグ内部に使ったパラメーターがすべて新しいスニペットで使える。

簡単、確実。

modx をコマンドラインからアップグレードする。

現在 Official にリリースされているmodxのバージョンは2.2.5-pl だが、結構バージョンアップが煩雑に行われていて、そのたび、バグが取れたり、使い勝手がよくなってきていて、ますます気にいってきたりするわけだけれども、ファイルサイズもだんだんと大きくなってきており、アップグレードするたびに、zipファイルをまずは自分のパソコンにおとしてきてから解凍し、外部のhost server にすべてをftp で転送するとなると、やたらに時間がかかってしまう。

しばらく前にhost 側にsshでログインし、コマンドラインからファイル展開を直接行う方法を説明しているサイトを見つけ、この方法を使って重宝しているので、ここに記しておく。

オリジナルの英文ページはこちら

上記ページはEvoluation 用に記述してあるが、revolution でも作業は同じ。

まずはホストサーバーのssh アクセスを有効にしてコマンドラインを使えるようにしておくのが第一歩。 自分の使っているホストはコンソールパネルからsshを有効にするだけで、コンソールパネル用のユーザーネームとパスワードでアクセスできるようになった。パソコンがLinux であれば、ターミナルから直接sshを起動、 Windows の場合はPuTTYとか、CygWinなどを実装しておく必要がある。

ssh username@server.com

First things firstで、まずは 既存のmodxファイルをサーバーのrootにバックアップしておく。 sshでログインすると最初はrootフォルダーにいるのだが、そのrootの下にpublic-htmlというフォルダーがあり、web アクセスができるのはこのpublic-html フォルダーから下の階層のみという仕組みになっているのを利用してバックアップをweb からはアクセスできないrootフォルダーにzipして保存してしまおうというわけ。(下のコマンドでは’~’ でroot指定している)

zip -r ~/my-modx-folder.bk.`date "+%Y.%m.%d.%H.%M.%S"`.zip my-modx-folder

これでrootフォルダー上に my-modx-folder.bk.date_of_backup.zip というようなアーカイブファイルができる。

次にmysqlのデータベースも念のためバックアップ。(使っている環境によって異なると思うので説明省略)

次にmodxの最新版をダウンロードしてくる。
これはmodxの最新版のダウンロードのページに行って、ダウンロードのリンク先をコピーし、これをターミナル画面上のwget コマンドに張り付けることになる。

wget path-to-the-latest-modx.zip

これをサーバー内部で解凍

unzip modx-2.2.5-pl.zip

modx-2.2.5-pl というフォルダが作成され(何千という)ファイルが展開される。

これをmy-modx-folder にコピーするのは cp -r コマンドを使うわけだが自分の環境ではcp にAlias がかかっているらしく、f parameter をつけてやらないといちいち上書きしますか、ときいてくるはめになる。
cp -rf modx-2.2.5-pl/* my-modx-folder
数分でファイルの展開が終了する。
次にmy-modx-folder/core/config/config.inc.phpのパーミッションを変更して書き換え可能にする

cd core/config
chmod 666 config.inc.php

あとはブラウザでsetupを実行するだけ。

my-domain.com/setup

 

7~8分で全作業が終了する(はず)

わかったつもりになってはいけない

地下室においてあるPCのWEBServerはIISで動いている。 いや、Windwos7がはいっていたので、気軽な気持ちでIISを導入し、うごかしてみたら、設定が簡単だったのと、PHPのサポートが意外と充実していたので、サーバーとして使うことにしたのだ。すでに2年ほど支障なく動いている。

もっとも、アプリケーションはPHPで動くModXだ。 asp、aspx ベースではない。Visual Studioも(タダだし)起動画面までは見てみたのだが、C#もVBも覚えるつもりがなく、 結局JavaScriptやCSSだけでWEBサイトを構築できるPHPベースのModXでうごかしている。

ひとつだけ問題があるとしたら、IISベースではFriendly URLがサポートされていないこと。 IIS自体はFURLはサポートしているのだが、別途設定しなければならない。これがApache ベースのサーバーではModXに付属してくる.htaccess ファイルで簡単に対応できる。

世の中よくしたもので、IISでこの.htaccess をそのまま使えるツールが存在する。 Helicon Ape というユーティリティなのだが、サーバー3本までは無料バージョンでサポートされている。 これを入れて、ModX側のFriendly URLのシステム設定をOnにするだけで、FURLが有効になる。 するとそれまでは
http://mysite.org/index.php? id=36
などという味気ないURLが
http://mysite.org/this_pabe.html
という”読みやすく覚えやすいFriendlyな”アドレスに書き換わる。

この組み合わせで半年ほど快適に使ってきたのだが、ある日突然うごかなくなってしまった。 なぜか、最初はわからなかった。
で、いろいろ調べた結果わかったのが、IISの設定。このサイト、.net frameworkをつかっていないのだからいらないだろうと、.netのサポートをIISのメニューから前の日に外していた。外した途端に動かなくなったわけで、ホームページ自体はPHPがきちんと動いて表示するが、リンクが全部だめになったのは、要するにApeが作動していなかったので、
http:/mysite.org/this.page.html
を Apeが以下に変換、
http://mysite.org/index.php ?q=”this page.html”
さらにこれをModXが読み込んで
http://mysite.org/index.php ?id=36 に変換
という書き換えができなくなっていたわけ。 つまりApe 自体はIISの.net frameworkの上で動いていたわけだ。

で、あらためてHeliconのページを読んでみれば

Helicon Ape is implemented as managed IIS 7 module and can be installed as .NET module on any ASP.NET-compatible IIS version. It works transparently for both server and client and can even be installed on a shared hosting account without administrative access.

.NET module だと、しっかり書いてある。(おい)

わかったつもりになっていてはいけません。

ModX Revolution2.2 とIIS の相性

modXの2.2 がリリースされてから2ヶ月ほど経ったが、今回自宅のサーバーに導入してみた。 ホストサービスのほうで運用しているサーバーはApache なのだが、自宅はWindowsに実装したIIS7だ。

で、インストールしてマネージャ画面に行ってみたら、なんとリソースツリーがない。メニューとお知らせは表示されるのだが メニューをクリックしても空白の画面が出てくるばかり。 ログアウトもできない。

インストールを繰り替えしてみたり色々やってみたが拉致あかず

サポートフォーラムに行って2.2のエントリーを眺めてみると、結構類似の問題が発生している模様、 その中で

「どういう訳か、IISではJS とCSSを圧縮するとうまく行かない」という記述があり、対策としてはPHPMyadminなどで直接mysqlデータにアクセスし、System settingの当該項目を圧縮あり(1)からなし(0)に変更すればよい、との書き込みを見つけた。

もっとはやく言ってよ。

早速SQLBUDDYでデータ内容を書き換えて解決。

 

JQueryの.load()を使ってみて complete: にはまった、という話

Query ライブラリーの中に.load()というmethodがあり、これを使うと、WEBページの一部に他のページをはめ込む、ということが簡単にできる。 たとえばmain.html というページがあり、 そこに<div id=”sections”></div> というセクションをつくっておき、 この部分にcontent1.htmlというページを差し込むためには
$(‘#sections’).load(‘content1.html’);
というjavascript 一行で済む。

これを使えば、content2.html, content3.html などというページを用意しておいて、Javascriptを使ってインターアクティブに(ページを全部ロードしなおすのではなく)ページの一部だけを差し替えることができるようになるわけだ。

これって、巷にいうAjaxだが、jQuery のAjax サポートは ajaxSetup というobjectががあって、この中で、Ajax関係の諸パラメーターを前もって設定することが可能、 で、とりあえず
$.ajaxSetup({
beforeSend: function() {
$(‘#sections’).css(‘visibility’,’hidden’);
$(‘#aContainer’).css(‘background’, ‘url(images/ajax-loader.gif) no-repeat center’);
},
complete:
$(‘#aContainer’).css(‘background’,’none’);
}
});
とやって、 ページをロードしたときに、前のページの表示を消し、バックグランドにロード中お待ちくださいのイメージをはっておき、ロードし終わったときに、これを取り除く、という 動作を付け加えた。

ところが実際に動かしてみると、ロードが完了して新しいページが表示された後でもイメージが消えない。 ブラウザの開発ツールで見ると、スタイルシート上、バックグランドイメージがそのまま残っている。つまり、complete: の部分が動いていない。

これで2時間ほどハマったわけだが、 結論からかいてしまう。
実は.load()というコマンドにはコールバック機能があり、 これを使って、ロードされた画面の初期化を行うためのjavascriptを指定していた($(‘#sections’).load(‘content1.html’,’doSomething’)) のだが、これがcomplete: に指定された処理を無効化してしまうようである。 jQueryの.load と complete: の部分のマニュアルをじっくり読んでそういう結論に達した。

というわけで、Complete: event ではなく Success:event に動作をぶら下げて解決。.load()ではなく、.get()を使うとすっきりしそうだが、詳しく調べてないのでこれでよしとする。

jQuery.ajaxSetup({
beforeSend: function() {
$(‘#sections’).css(‘visibility’,’hidden’);
$(‘#aContainer’).css(‘background’, ‘url(images/ajax-loader.gif) no-repeat center’);
},
success:
$(‘#aContainer’).css(‘background’,’none’);
}
});

$ajax を使うと、もっときめ細かいAjax操作ができるそうだが、現状ではこれで十分。

一応動いている証拠は ここに
http://shogishack.net/modx/pages/assess-the-situation/exchanging-pieces/

ModX/WayFinderで作ったメニュのa href部分をjqueryで一括加工し、それぞれのアイテムをクリックすると、Jumpではなく、.loadが呼び出されるようになっている。

ModXと jQuery を使ったAjax, なかなか相性がよさそうである。

ModXのテンプレート変数(Template Variable, or TV)のすごさが判ってきた

 

とにかく実際に試してみる、とういのが物事なんでも大事なようで、オンラインのチュートリアルでわかったようなつもりになっていても、 実際に経験してみてその効果が実感できるということがよくわかったのが、このModXのTVの使い方

その1: 新しいページを作成してそこに表示するメニューをまったく別の親からはじめようと思ったのだが、メニュー部分はテンプレートに入っている。 テンプレートに新規のものを指定することももちろん出来るわけだが、今回はメニュー用Snippetのwayfinder のstartidの指定部分を`20`という固定から menurootというTVを作って`*menuroot`という変数指定とし、default値を20とすることで、従来のページには影響を与えず、新規のページについては何もしなければデフォルトのメニューを表示、メニューの表示を違う親から始めたければTVの値を指定できるようにして解決。

その2: その新しいページの固定幅を広くしたい必要が生じた。 CSSには .wrapper { width:750px; .. というクラスで指定してあるのだが、 新しく .wrapperWide{ width:1000x;   というクラスを指定し、 テンプレート上の

<div class=”wrapper”…  という部分を <div class=”wrapper[[*narrowOrWide]]….   として narrowOrWide というTVを追加する。   narrowOrWide のデフォルト値は空白なので、 従来のページはそのまま。 新しいページのnarrowOrWideのTV値を”Wide” とすることで解決。 

システムの仕組み上そうなるのが当たり前なのだが、 ページがうまく表示されたときには感動した。

Way of wayfinder

ModXのWayfinderはナビゲーションリストを作るときに、base_urlからの相対パスを出力する。 よってテンプレートに<base>tagで [[++site_url]]指定をしてやる必要がある、これを指定せずに階層の下がったページからナビゲーションしようとすると システムはカレントパスを相対パスの前に追加するからリンク先が存在しない事態になる。

Make sure you have the following in the the <head> section of your template:
Code:

<base href=”[(site_url)]” />
without the above code in the site template, the navigation menu  wayfinder will generate will not render correct path.   This is because Wayfinder generates the path from base url. If you left <base> tag out, the system will always start from current path.
Let me describe what had happened to me.
Target document tree looks like below;
one – two
  |_    three
  |__ four
  |__ five
The wayfinder sinppet generates a list with correct hrefs and  works fine in the page one.
When navigated to page two, then the links generated for other pages are incorrect.
if you are in second level, then the path will start as http://…/one.  the wayfinder adds /one/three.  Therefore the generated path is http://…../one/one/three,  rather than http://…./one/three  etc., (“one/ “is repeated twice)
Simply adding the <base href=”[[++site_url]]”> line at the <head> section of the template solve the issue.