= Using Amrita with cgi
== summary
This document describes how to use amrita with cgi programing using
series of sample code.
The sample is a web bookmark system.
You can see the demo at...
http://www.walrus-ruby.org/amrita/
== The model class
At first, we make the model class.
:include: sample/cgi/bmmodel.rb
The class +Item+ is the bookmark items. It has three attributes:
group, name, url.
The class + BookmarkList is collaction of +Item+. It contains +Item+ s
separated by groups and is able to save and load the list to/from a
file.
The model class has nothing to do with HTML. So, it can be unit-tested
easily.
== bookmark.cgi
bookmark.cgi displays bookmark list. And it accepts new bookmark entry.
=== html template file
bookmark.cgi uses this template.
:include: sample/cgi/bookmark.html
=== code
This is the code of bookmark.cgi
:include: sample/cgi/bookmark.cgi
=== use a model class object for amrita's model data
class Item
include Amrita::ExpandByMember
def link
e(:a, :href=>url) { url } # http://www.xxx.com/
end
end
Ruby's class is an open class: it can be edited by user without
modifing the original code. The class +Item+ is defined in other
source file.
We make this class include Amrita::ExpandByMember and add a method
named +link+ so that it's method can be used directly by template.
We will provide +Item+ objects for id +items+ and because +Item+
object is a Amrita::ExpandByMember object,id +name+ and +link+ will be
used as method names.
+url+ is a method related to MODEL so it should be defined in model
class (bmmodel.rb). And +link+ contains information about VIEW (HTML
presentation) so it's better to put it to the view related
source(bookmark.cgi).
=== make a forms element
If you add a new item, the next page displayed contains the selection
of groups with default of the selected group.
The model data here....
:form => {
:group_sel=>e(:select, :name=>"group_sel") {
groups.collect do |g|
if g == selected_group
e(:option, :value=>g, :selected=>"selected") { g }
else
e(:option, :value=>g) { g }
end
end
},
}
generates this html.
And this HTML is inserted to the element with id +group_sel+.
=== using the compiled code
Amrita::TemplateFileWithCache::set_cache_dir(CACHE_PATH)
tmpl = Amrita::TemplateFileWithCache[TEMPLATE_PATH]
tmpl.use_compiler = true
tmpl.expand($stdout, make_model_data(bm,group))
Amrita::TemplateFileWithCache is a kind of Amrita::TemplateFile that
can reuse compiled code stored in cache file.
If there is the cache data matches to +TEMPLATE_PATH+ in +CACHE_PATH+
and it is younger than template itself, amrita reuse the compiled code
automatically.
CAUTION: be careful to prevent users to edit the cache file.
Currently, amrita does not check the cache file weather it was created
by amrita nor unmodified . So if someone can edit it, he or she can
insert any dangerous code into it to be executed by amrita.
It's *YOUR* resposibility to protect the cache files from
crackers. Don't use TemplateFileWithCache::set_cache_dir if
you don't understand this.
---
== using amrita script as cgi
This is a viewer of bookmark written in amrita-script.
:include: sample/cgi/bookmark.ams
How to run in apache.
* set AllowOverride FileInfo and Options ExecCGI to
some +cgi-bin+ Directory directive in httpd.conf
* put bin/amshandler to that directory
* put .htaccess to that directory
AddHandler amrita-script ams
Action amrita-script /amrita/cgi-bin/amshandler
---
== using bookmark.rb under mod_ruby
sample/cgi/bookmark.rb is a script can run under mod_ruby.
LoadModule ruby_module /usr/lib/apache/mod_ruby.so
RubyRequire apache/ruby-run
Alias /amrita/cgi-bin/ /home/tnaka/cvswork/amrita/sample/cgi/
Options ExecCGI
SetHandler ruby-object
RubyHandler Apache::RubyRun.instance
SetEnv AmritaCacheDir /tmp/bookmark # be careful
---
== using amrita-script under mod_ruby
LoadModule ruby_module /usr/lib/apache/mod_ruby.so
Alias /amrita/cgi-bin/ /home/tnaka/cvswork/amrita/sample/cgi/
RubyRequire amrita/handlers
SetEnv AmritaCacheDir /tmp/bookmark
Options ExecCGI
SetHandler ruby-object
RubyHandler Amrita::AmsHandler.instance
---
== X
=== code and output
code:
output:
=== description