On Jun 22, 2:31 pm, Dave Howell <[email protected]> wrote:
> I've spent a couple hours prowling through Sequels source code trying to
> figure out how to accomplish this. In the process, I've become really really
> impressed with Sequel. Wow, there's a phenomenal amount of flexibility in
> there.
>
> ***
>
> I've figured out that all the various templating engines for converting
> regular Ruby stuff into HTML for web pages are going to be 'too little too
> late' for me, and I'm moving to building the entire page dynamically in my
> controller. I've created a couple of new methods on String to make that a bit
> easier. "Something or other".to_html(:p) becomes "<p>Something or
> other</p>", for example. I also have a .to_link method:
> myProductDataset.collect {|product|
> product.name.to_link("?id=#{product.pk}")}
>
> I think I can clean things up a lot more, though, with a slightly different
> approach. I'd like to teach Sequel::Model to take over a lot of the work of
> making db data HTML-ready.
> It would use a subclass of String (call it WebString) that Sequel::Model
> would use as the base type for all the string values. WebString would have
> .to_html and .to_link methods, where .to_link automatically creates a link
> tag based on the primary key of its model. (I'll probably switch from
> directly using the model's primary key to using some kind of session-specific
> id code at some point.)
>
> My ultimate vision goes something like this:
> I build a dataset just like usual. I tell it that stuff in the second
> column should have its .to_html method overridden with .to_link. I add the
> dataset to an array or other output collector. My work is now done. When
> it's time to create the view, my output routine checks for objects that
> respond to .to_html, and calls it if they do. The dataset itself responds to
> .to_html by building a table (or maybe it uses nested DIV tags, or whatever),
> and in turn calls .to_html or .to_s on its rows, which in turn calls .to_html
> on the fields. The final result is an HTML table with one column containing
> hyperlinks to single item pages.
>
> I suspect at some point .to_html will decompose to XML objects rather than
> directly to plain strings. But I know the first step is to upgrade the
> functionality of my dataset output objects.
> I *think* this can be done by creating a plug-in and overriding some existing
> methods. However, I haven't yet been able to figure out *what,* exactly, I
> should consider overriding to do this. Can anybody give me some suggestions
> as to where to look?
I'm with Don in that I'm not sure your approach is a good idea, but
Sequel does try to be flexible. I'm not sure of the exact API that
you want to use. From your description, I'm imagining something like
this:
ds = Product.select(:id, :name, :description).filter(...)
ds.map_column(:name){|p| p.name.to_link?("?id=#{product.pk}")}
ds.to_html # Returns html table like:
# Name | Description
# _Foo_ | A nice foo
# _Bar_ | A nicer bar
Where _Foo_ and _Bar_ would be linked to specific pages for items.
To make all strings used in model objects automatically be WebStrings,
you can take the approach of the force_encoding and typecast_on_load
plugins, and have instance methods in the plugin that modify string
values that come from the database:
def set_values(row)
h = {}
row.each{|k, v| h[k] = typecast_value(k, v)}
super(h)
end
def typecast_value(column, value)
s = super
s.is_a?(String) ? WebString.new(s) : s
end
The general strategy for the to_html handling things would be using a
plugin that adds to_html and map_column dataset methods:
def map_column(column, &block)
(@map_columns ||= {})[column] = block
end
def to_html
cols = opts[:select] - [:id]
all.map do |p|
cols.map do |c|
if pr = @map_columns[c]
pr.call(p)
else
p.send(c).to_html(:td)
end
end.to_html(:tr)
end.to_html(:table)
end
The end result would be that when you call to_html on a dataset, it
will retrieve all objects. For each object, it will turn each column
in the dataset into a table data cell (allowing overrides that you
specify via map_column), wrapping the whole object in a table row, and
wrapping all rows in a table.
I haven't tested any of the above code, but that would be the basic
approach I would start with if I had your design in mind.
Jeremy
--
You received this message because you are subscribed to the Google Groups
"sequel-talk" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sequel-talk?hl=en.