Jeff Barczewski
2006-Jun-14 19:57 UTC
[Masterview-devel] Consolidated MasterView IO is commited, need to think about best way to configure it with initializer
I committed the MIO code and changes. I still need to update the initializer
and sample configs, but I wanted your input on the best way to configure
this.
Before we had a bunch of loose constants and this was starting to balloon.
With the new consolidated MasterView IO (MIO) I encapsulated things for each
src and dst.
Here is a sumamry of how MIO works
There is an open struct called MasterView::IOMgr (short for manager)
One can set up any number of MIOTrees under this IOMgr (a MIOTree is a
source or destination for templates, erb, files, ...)
So typically we will have trees setup for templates, erb, and backup. This
corresponds to reading/writing template, reading/writing .rhtml,
reading/writing backups files.
These MIOTrees are designed to be portable, I have implemented a FileMIOTree
and a StringHashMIOTree. I have stubbed ActiveRecordMIOTree (for storing
templates in db), and I have a RailsErbCacheMIOTree which will be used to
write to the Rails ERB cache (bypassing the intermediate .rhtml file
generation).
IOMgr.template = FileMIOTree(''app/masterview'',
''.html'') # root_path,
default_extension for templates
IOMgr.erb = FileMIOTree(''app/views'',
''.rhtml'') # root_path,
default_extension for generated erb
IOMgr.backup = FileMIOTree(''tmp/masterview'') # root_path,
default_extension
for backups, if nil then no backups will be created.
Similarly you can change to a string_hash mechanism (great for testing) by
simply doing
template_hash = {}
IOMgr.template = StringHashMIOTree(template_hash, ''.html'') #
root_path,
default_extension for templates
erb_hash = {}
IOMgr.erb = StringHashMIOTree(erb_hash, ''.rhtml'') # root_path,
default_extension for generated erb
backup_hash = {}
IOMgr.backup = StringHashMIOTree(backup_hash) # root_path, default_extension
for backups, if nil then no backups will be created.
And to create a pseudo file simply
template_hash[''foo/bar.html''] = ''my template
html''
and it is available to be read.
Written files show up as new entries similarly.
assert erb_hash[''cat/dog.rhtml'']
In addition to that one can apply any number of filters to the objects that
are read/written. I have created TidyMIOFilter, EscapeErbMIOFilter, and
LoggingMIOFilter. First runs tidy on the template after reading it before
passing it on, next one escapes <%= %>, and last one logs reads and
writes.
I stubbed out a CachingMIOFilter as well but is not implemented yet.
You can configure what filters will be applied to the underlying MIO objects
(which the MIOTree hands out). You can do this by provding a block to the
MIOTree when created. for instance.
IOMgr.template = FileMIOTree(''app/masterview'',
''.html'') do |mio|
mio.apply_filter TidyMIOFilter
mio.apply_filter LogggingMIOFilter
end
This plugs Tidy on top of FileMIO and then Logging on top of it, so Logging
will be hit first, then Tidy, then FileMIO. Each filter can do whatever it
wants to the content being passed through.
Since this is somewhat advanced and most users will simply want to turn on
or off ones we have provided and to ensure they are invoked in the proper
order, I provided a default block which you can toggle on and off the
standard filters with hash options.
IOMgr.template = FileMIOTree(''app/masterview'',
''.html'', :caching => true,
:tidy => true, :escape_erb => true, :logging => true)
So when this tree creates FileMIO objects it adds the appropriate filters
before giving back the object.
You would obtain one of these FileMIO object simply by doing
fileMIO = IOMgr.template.path(''foo/bar.html'')
with that MIO object you can easily read or write to it as well as check if
exist?, identical?(to output).
template = fileMIO.read
or
template = IOMgr.template.path(''foo/bar.html'').read
to write an erb we use
IOMgr.erb.path(''foo/bar.rhtml'').write(content)
So we have things nicely encapsulated for each tree( the root_path, the
default extension, caching, tidy, escape_erb, logging).
How do we bring this out to the user in an easy to configure manner??
Do we take this simple approach below, or do we need to somehow break this
out into separate constants again?
IOMgr.template = FileMIOTree(''app/masterview'',
''.html'', :caching => true,
:tidy => true, :escape_erb => true, :logging => true)
One of the only constants I didn''t stick in the trees yet was the
MasterView
Template pattern, but I could see it being set as a hash value too.
So Deb looking for some of your intutiveness here on making this easy for
users.
Then once we come up with an approach we can update the samples you created
and the documentation.
All in all, I think this is going to work out really well with this io
consolidation. Everything is handled centrally and we can easily switch from
one IO mechanism to another and extend however we see fit.
I am open to additional ideas and naming suggestions if you don''t like
my
terms MIOTree, MIO objects. I spent all my creativity on the code and
didn''t
have much left for naming :-)
I created several *mio_tests to exercise the functionality.
And if I hadn''t mentioned before, a natural extension of this product
is to
serve these templates out of a database so that one can keep all the moving
parts in the db (great for backups and security). One place to backup all
the things that are changing regularly. So that''s why the
ActiveRecordMIOTree will exist.
We have discussed going direct to the rails ERB cache so I stubbed that out
as well.
It will be as simple as changing out the Tree type and providing enough
configue information to get it using the new location.
This also makes it great for testing now, since we can put stuff directly
into hash and not touch file system at all.
So when thinking about the configuration changes, think also about these
other possibilities, so when we turn on this functionality, the
configuration capabilities will be able to accomodate it. Most likely for
ActiveRecordMIOTree we will simply need a table or query, although it could
get more complicated with ability to save x old versions, etc. Most of the
time these things can be provided via a hash to keep our interface flexible
enough.
Let me know what you think, and how we should approach the configuration of
this new functionality.
Thanks,
Jeff
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
http://rubyforge.org/pipermail/masterview-devel/attachments/20060614/a1ab8990/attachment.htm
Deb Lewis
2006-Jun-14 21:49 UTC
[Masterview-devel] Consolidated MasterView IO is commited, need to think about best way to configure it with initializer
Jeff - ok, lots of good stuff here for me to chew on! Propose I take a first pass at things tonight to get the initializer changes I''ve already got integrated into your new stuff, then we can take a second pass once all the pieces are back together and figure out where we need to work on naming, config-ability, etc. I''ll have a much better sense of how this all "feels" after going through what you''ve done, but on first read of your description sounds very good. ~ Deb -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/masterview-devel/attachments/20060614/2a2f9683/attachment-0001.htm