ZopeでWebページを作る
Note: This is the print view with all the tutorial pages on one page. The paginated version is available here, if you prefer that.
まずは設定を
いよいよZope上にWebサイトを作っていきます。でもちょっとまって。もし初めて使うZopeのインスタンスなら先に設定しなければいけないことがあります。
ZMIの表示用文字コード指定
Zope自身は標準のままではどんな文字コードを使っていいのかを知りません。そのため、これから作るWebサイトの文字エンコードを教えてあげる必要があります。そのためにまずはZopeのルートフォルダを表示し、プロパティータブをクリックしてください。
ここに、プロパティー値を以下の値で追加します。
| id: | management_page_charset |
|---|---|
| type: | string |
| value: | utf-8 |
もしWebサイトをUTF-8以外の文字コードで作りたいのであれば適切な値に置き換えてください。しかし、特に強い理由がないのであればUTF-8にしておいた方が良いでしょう。
Note
zope.conf の設定に default-zpublisher-encoding がある場合はこの行に上記の management_page_charset と同様に utf-8 を設定して下さい。詳しくは FAQ/ページテンプレートと日本語 も参照して下さい。
index_htmlを作る
設定も終わったので、さっそくWebページの作成に入りましょう。
Webサイトを作るとき、おそらく一番最初に表示されるindex.htmlから書き始めるでしょう。Zopeでは IDには"."を含めない という慣例 [1] があるので、大抵は . の代わりに _ を使用します。このルールに従ういindex.htmlではなく index_html という名前でWebページを作ります。
| [1] | PythonやDTMLでは'.'を特別な意味で使用するため、'.'を含むIDを扱う場合に工夫が必要になります。最初のうちは無用なトラブルを避けるため、'.'を'_'に置き換えた方が良いでしょう。 |
既存のindex_htmlを削除して新しく作る
まずは、ZMIでルートフォルダを表示します。
http://localhost:8080/manage
Zopeインスタンスを作るとルートフォルダにindex_htmlという名前のオブジェクトがあります。このオブジェクトはインスタンス作成直後に http://localhost:8080/ にアクセスしたときに表示される Zope Quick Start ページのためにあります。ここではチュートリアルの都合上、一旦削除してください。
削除するには、index_htmlオブジェクトの左端にあるチェックボックスにチェックを入れ、ページ下端のDeleteボタンを押します。
次に、新しいindex_htmlを作ります。ワークエリアの右上のプルダウンメニューから DTML Document を選択・追加してください。ここで間違えてDTML Methodを選ばないようにしてください。DTML DocumentとDTML Methodの違いについては後述します。
DTML Document を追加するために、オブジェクトの名前などを求められますので、以下のように入力します。
| ID: | index_html |
|---|---|
| Title: | トップページ |
Titleはとりあえず'トップページ'としましたが、他の好きな文字列を入れてもかまいません。また、手元に作成済みのHTMLファイルがあれば、Fileフィールドを指定してファイルから読み込ませる事も出来ますが、今回はFileフィールドは空欄のままにしておきます。入力が終わったらすぐに編集するので Add and Edit ボタンを押してください。
index_htmlにHTMLを書く
それではindex_htmlを編集しましょう。既に編集用の画面が表示されているはずですが、先ほど Add ボタンを押してしまった場合はフォルダのオブジェクト一覧の画面に戻っていると思いますので、index_htmlをクリックして編集用の画面に移動します。
なにやらHTMLが書かれていますが、見慣れないタグ dtml-var が使われています。dtml-varについてはこのチュートリアルの後の方で使い方を説明しますので、とりあえずテキストエリアに書いてあるHTMLを全て消してしまいましょう。消したら代わりに以下のHTMLを入力してみてください:
<html>
<head>
<title>トップページ</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<h1>トップページ</h1>
</body>
</html>
入力したら Save Changes ボタンをクリックして保存しましょう。
Note
metaタグで文字コードを指定しています。この指定を行わないと、一部のブラウザでは文字コードを正しく判別できず、文字化けの原因となってしまいます。
作成したWebページを表示する
それでは今作ったページを表示してみましょう。ワークエリアの上端にある View タブをクリックしてください。
あるいは、以下のURLでも今作ったページを表示することが出来ます:
http://localhost:8080/ http://localhost:8080/index_html
フォルダに index_html がある場合はZopeが自動的にそれを表示してくれます。このあたりはapacheやIISと同様の動作です。
これで、HTMLの表示を行うことが出来ました。ここまではユーザーインターフェース以外はそれほど特別な部分はありませんでしたが、まずはapacheなどのWebサーバーと違わない部分からZopeを使っていきましょう。Web上で操作できるという点以外は、ディレクトリがあり、DTML Documentというファイルのような物があり、そこにHTMLを書くということをまず理解してください。
画像を表示する
ここまででHTMLをZope上に置けるようになりました。次は、HTMLの次に重要な画像を置いてみましょう。
画像をZope上に作成する
まずは、ZMIでルートフォルダを表示します。最初にindex_htmlを編集したときと同じフォルダをワークエリアに表示してください。URLは前回と同じです:
http://localhost:8080/manage
最初のindex_htmlと同じ様に、画像オブジェクトを追加します。ワークエリア右上のドロップダウンリストから Image を選択して追加してください。
追加時のIDなどは今回は以下のように設定しました。
| ID: | neko |
|---|---|
| Title: | 猫 |
| File: | neko.jpg |
ここで、Zope上で使用する ID には拡張子を設定していません。最初に説明したように . の使用を避けるという事と、Zopeがコンテンツタイプを自動的に認識してくれるので付けなくても問題ないという事もあります。最初のチュートリアルですので無用のトラブルを避けるため、ここでは拡張子無しで登録します。
Addボタンを押すとルートフォルダが表示されます。一覧の中に今追加した neko があると思いますのでクリックしてください。nekoオブジェクトの編集画面が以下のように表示されます。ちゃんと登録した画像のサムネイルが表示されています。簡単ですね。
もし、ファイルや画像を一つ一つZMI経由で登録するのが面倒な場合は、Zopeが標準で提供している WebDAV 機能を利用して一括登録することも出来ます。詳しくは WebDAVを使う を参照してください。 (現在未作成です。もうしばらくお待ちください)
画像をHTMLに埋め込む
次は用意した画像をindex_htmlで表示できるように、index_htmlオブジェクトを編集します。と言っても全く難しいことはなく、以下のように <img> タグを書くだけです:
<img src="neko" alt="" title="猫" width="320" height="320" />
このように書くと、とりあえずWebページに画像を表示できるようになります。同様の手順でapacheやIISで作成していた静的(非cgi)なWebサイトをZope上に作ることが出来ます。しかし、せっかくZopeを使うのだし、もうすこしZopeの機能を使いたいところです。
そこで、次はZopeの機能の一つである DTMLタグ を利用した記述方法を使ってみましょう。
DTMLタグでWebページを作る
今編集している index_html は、 DTML Document という種類のオブジェクトです。このオブジェクトにはHTMLを書くことが出来ますが、同様に DTMLタグ を記述することが出来ます。細かい説明は後回しにして、とりあえず使ってみましょう。
DTMLで画像を埋め込む
さきほど<img>タグを書いた部分を以下のDTMLタグで置き換えます:
<dtml-var neko>
置き換えたら保存して、表示してみましょう。さきほどの<img>タグを記述していた時と同じように表示されると思います。これは、 <dtml-var neko> という文字列を使っているブラウザが理解してくれたわけではなく、ZopeがHTMLに変換してから出力しています。表示しているページのソースコードを見てみましょう。ブラウザの表示メニュー等からHTMLソースを表示することが出来ると思います。
出力されたHTMLソースの、<dtml-var neko>を書いたあたりは以下のようになっていると思います:
<img src="http://localhost:8080/neko" alt="" title="猫" height="320" width="320" />
<dtml-var neko> と書いただけですが、かなり詳しくHTMLに変換してくれています。この変換は、<dtml-var neko>と書いた部分でnekoオブジェクトにHTML出力の依頼が行われ、nekoオブジェクト(Imageオブジェクト)が自分自身をどのようにHTMLに出力したいかを知っているので、titleやサイズ情報が出力されています。
DTMLで色々な情報を表示する
DTMLは、同一フォルダにある他のオブジェクトの情報以外にも色々な情報を表示することが出来ます。その一例としてタイトルをDTMLで表示してみます。DTMLタグで <dtml-var title> とすることでそのページのタイトルを表示することが出来るようになります。以下のようにindex_htmlを書き換えてみてください:
<html>
<head>
<title><dtml-var title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<h1><dtml-var title></h1>
<dtml-var neko>
</body>
</html>
書き換えた箇所は<title>タグと<h1>タグの所です。このページを表示すると、<dtml-var title>と書いた部分が置き換わって、さきほどまでと同様に トップページ という文字列が表示されます。先ほどからHTMLを編集しているエディットボックスの上に Title というエディットボックスがありますが、ここに設定された値が <dtml-var title> に置き換わって表示されています。
dtml-varはtitle以外にも、色々な情報を表示することが出来ます。以下はその一例です。
| id: | オブジェクトのidです。例: index_html |
|---|---|
| title: | オブジェクトのtitleプロパティーです。例: トップページ |
| title_or_id: | オブジェクトのtitleかidです。titleが優先されますが、titleが空欄の場合にはidが表示されます。 |
| absolute_url: | オブジェクトのZope上の絶対URLです。例: http://localhost:8080/index_html |
| bobobase_modification_time: | |
| オブジェクトの最終編集時刻です。例: 2006/02/18 21:36:12.640 GMT+9 | |
さっそくindex_htmlに書き込んで実験してみましょう:
<html>
<head>
<title><dtml-var title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<h1><dtml-var title></h1>
<ul>
<li><dtml-var id></li>
<li><dtml-var title></li>
<li><dtml-var title_or_id></li>
<li><dtml-var absolute_url></li>
<li><dtml-var bobobase_modification_time></li>
</ul>
<dtml-var neko>
</body>
</html>
上記ようにdtml-varで表示できる値は、大きく分けて以下の4種類に分類されます。
- idやtitleなど、オブジェクトが持っているプロパティー
- absolute_urlやbobobase_modification_timeのような、オブジェクトの状態によって変化する情報(実際にはオブジェクトが持っているabsolute_url等の関数を呼び出しています)
- nekoオブジェクトのような、他のオブジェクトの情報
- 上位のフォルダなどが持っている、上記1~3の情報
4番目の項目は、 獲得(acquisition) と呼ばれるZopeの機能です。dtml-varで指定した値が自分自身に無い場合、自動的に自分が属している親フォルダに値を問い合わせます。例えば、 <dtml-var management_page_charset> と書くことで、 utf-8 という文字列が取得され、表示されます。
Note
実は3番目の項目も、獲得によって取得されています。nekoというプロパティーや関数がオブジェクト自身に無い場合、親フォルダに問い合わせが行われます。親フォルダは、親フォルダに属しているプロパティー、関数、子オブジェクトから neko を探しだして問い合わせ元に返します。親フォルダにもなかった場合は、さらに親フォルダへと問い合わせが行われます。
これでdtml-varの1つめの記述方法について大体理解できたと思います。次は、dtml-varを利用してページを分割し、再利用する方法について見ていきましょう。
HTMLを分割して再利用する
nekoオブジェクトはdtml-varで呼び出すことで<img>タグを生成しましたが、Imageオブジェクト以外でも同様の仕組みを持っているオブジェクトがいくつかあり、 DTML Document や DTML Method もそのうちの一つです。
DTMLでページを分割・再利用する
まずは例として、 standard_html_header, standard_html_footer を読み込んでみます。これらは他のページから使われることを想定してZopeが最初から用意してくれているDTML Methodです(DTML Documentとの違いは後述します)。
さっそくindex_htmlを以下のように書き換えてみてください:
<dtml-var standard_html_header>
<h1><dtml-var title></h1>
<ul>
<li><dtml-var id></li>
<li><dtml-var title></li>
<li><dtml-var title_or_id></li>
<li><dtml-var absolute_url></li>
<li><dtml-var bobobase_modification_time></li>
</ul>
<dtml-var neko>
<dtml-var standard_html_footer>
先頭から<body>までと、</body>から最終行までを置き換えました。viewで表示してみると、これまでと同様に表示されるはずです。しかし、一部のブラウザでは文字化けするようになってしまうと思います。これは、standard_html_headerがこれまでのindex_htmlに記述していた以下の行を出力していないためです:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
この問題を修正するため、standard_html_headerの記述を確認してみましょう。ZMIで確認してみてください。以下のソースが書かれていると思います:
<html> <head><title>&dtml-title_or_id;</title></head> <body bgcolor="#FFFFFF">
新しいdtmlの記述方法が出てきました。ここで使われている &dtml-title_or_id; は <dtml-var title_or_id> と同義です。HTMLの文字実体参照と同じ文法で & で始まって ; で終わっています。
それではstandard_html_headerにmetaタグを追加しましょう:
<html>
<head>
<title>&dtml-title_or_id;</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body bgcolor="#FFFFFF">
ここで、先ほど学んだ獲得を用いて、ルートフォルダに設定したmanagement_page_charsetの値を利用するようにしてみましょう。metaタグを以下のように書き換えます:
<meta http-equiv="Content-Type" content="text/html; charset=<dtml-var management_page_charset>">
これでももちろんOKですが、metaタグの中にdtmlタグが書かれるのはHTML的に微妙な感じがします。そこで &dtml-...; を使って以下のように書き換えます:
<meta http-equiv="Content-Type" content="text/html; charset=&dtml-management_page_charset;">
これで、どのページからも利用できるstandard_html_headerの用意が出来ました。standard_html_headerにサイト全体で共有したい内容を書いておくことで、ページ毎に毎回同じような内容を記述しなくても良いようになります。
standard_html_footerも同じように利用できますので、以下のように書き換えてみましょう:
<hr> LastModified: <dtml-var bobobase_modification_time> </body> </html>
viewで出力結果を確認してみてください。だんだんそれらしくなってきたと思いませんか?
Note
DTMLの記述方法には4つの種類があります。
- <dtml-var title_or_id>
- &dtml-title_or_id;
- <dtml-var expr="title_or_id()">
- <dtml-var "title_or_id()">
1,2は同義、3,4も同義です。3,4の記述方法はPython式を記述する場合の書き方で、プロパティーの取得(titleなど)と関数呼び出し(idやtitle_or_idなど)を明示的に書き分ける必要があります。手間が増える分細かい制御が出来るため、 <dtml-var expr="absolute_url().split('/')"> といった関数呼び出しが可能です。
HTML4.0 strict?やXHTMLとして見たときに正しいのは2と3ですが、DTMLはHTMLに変換されるため出力結果は文法違反にはなりません。とはいえ、普段から文法を気にした方が良いのは確かだし、DreamWeaverなどのツールを使用する場合には正しい文法で記述しておく事が必要になるでしょう。
DTML DocumentとDTML Methodの違い
index_htmlがDTML Documentだったのに対して、standard_html_header,footerはDTML Methodです。これらの違いは何でしょうか?比較のためにそれぞれの編集画面を表示してみましょう。
それぞれの編集画面をよく見比べてみると、タブの数に違いがあります。DTML Documentには Properties タブがありますが、DTML Methodにはありません。DTML Method自身はプロパティーを持てないため、プロパティーを編集するためのタブが用意されていないのです。
ここで、standard_html_headerのコードに <title>&dtml-title_or_id;</title> が利用されていた事を思い出してください。もし、standard_html_headerがDTML Documentだった場合、title_or_idの取得はstandard_html_headerオブジェクト自身から行われる事になります。その結果、title_or_idの値取得先はindex_htmlオブジェクトであって欲しいのに、standard_html_headerオブジェクトを参照してしまい、 standard_html_header という文字列が出力されてしまいます。
このように、 DTML Methodオブジェクトは主体にはなりません 。このため、DTML Methodのコードで値の参照を行うと、主体となるオブジェクトに問い合わせて値を取得することになります。もし、DTML Methodオブジェクトを直接URLで指定して表示した場合、主体となるオブジェクトを探して親フォルダに問い合わせが行われて、親フォルダのtitleなどが取得される事になります。
まとめると、 他のオブジェクトから呼び出される場合は、DTML Methodを使うようにする ということになります。
新しいページやフォルダを作りセキュリティー設定を行う
Webサイトが1ページだけでは寂しいので、新しいページを作ってみましょう。
hello_htmlオブジェクトを作る
それでは、ルートフォルダにDTML Documentオブジェクトを作成してください。IDとTitleは例として以下を設定します。
| ID: | hello_html |
|---|---|
| Title: | Hello |
作成したhello_htmlの編集画面に以下のコードを書いてSaveします:
<dtml-var standard_html_header> <h1>&dtml-title_or_id;</h1> <dtml-var neko> <dtml-var standard_html_footer>
共通部分を再利用しているため、これだけの短いコードで一つのページが完成しました。
フォルダを作ってhello_htmlを移動する
次はフォルダを作成します。作り方はDTML Documentなどと同様にドロップダウンメニューからFolderを選択します。フォルダ新規作成画面には、DTML Document作成時と異なり、Create public interfaceとCreate user folderのチェックボックスがあります。それぞれ、index_htmlページと、フォルダ以下専用のアカウント管理機能の用意をしてくれますが、今回は必要ありません。IDとTitleは例として以下を設定します。
| ID: | subfolder |
|---|---|
| Title: | サブフォルダ |
フォルダを作成したら、そのフォルダ内にページを用意しましょう。今回は、先の例でルートフォルダに作成済みのhello_htmlをsubfolderへ移動します。
オブジェクトを移動するには、ルートフォルダでhello_htmlの左横にあるチェックボックスをチェックし、ページ下端の Cut ボタンを押します。ボタンを押しても画面上はあまり変化がありませんが、Zope内部で(正確にはcookieに)状態が保存されています。次に、subfolderへ移動して Paste ボタンを押してください。subfolderフォルダにhello_htmlオブジェクトが表示されたと思いますので、viewでページの表示を確認するか、以下のURLでページを表示してみましょう:
http://localhost:8080/subfolder/hello_html
hello_htmlはstandard_html_header等を呼び出していますが、subfolderにはstandard_html_header等はありません。これらは獲得(acuisition)機能により親フォルダのものが利用されています。このように、共通のパーツを親フォルダに置くことによって全てのサブフォルダで再利用することが出来るようになります。
フォルダにセキュリティー設定を行う
最後に、作成したフォルダの閲覧権限を設定しましょう。通常はだれてもページを表示することが出来るようになっていますが、表示するための権限を 認証済みユーザー のみに制限する設定を行います。
セキュリティー設定のために、subfolderのSecurityタブを表示してください。
Securityタブの各行は様々な機能を表しており、各列はその機能を実行するために必要な権限を表しています。Zopeではこの権限をRoleと呼びます。各Roleには以下の役割があります。
| Anonymous: | 認証していない全てのアクセスに与えられます |
|---|---|
| Authenticated: | 認証済みの全てのアクセスに与えられます |
| Manager: | 認証したユーザーがManagerのRoleを持っている場合に与えられます |
| Owner: | 認証したユーザーが所有しているオブジェクトへのアクセス時に与えられます |
また、左端の Acquire は、上位フォルダのセキュリティー設定を継承するかどうかのチェックボックスです。このフォルダのセキュリティー設定を親フォルダから独立した設定にしたい場合はチェックボックスをOFFにする必要があります。
セキュリティー設定の例として、View(ページを閲覧する機能)に必要な権限をAuthenticatedのみに制限します。View機能の行のチェックボックスから、AcquireをOFFにし、AuthenticatedをONにしてページ下端の Save Changes ボタンを押してください。
これでこのsubfolder以下の閲覧は認証無しでは行えなくなりました。確認のためには、別のブラウザを使うか、今使っているブラウザを起動し直してください。
Note
このフォルダにUser Folderオブジェクトを追加するとacl_usersフォルダが作成され、このフォルダ以下でのみ有効なユーザーを管理することが出来るようになります。












