== Version 0.30.0
Another pragmatic release. The Nitro development team worked over
the submitted tickets and provided many bug fixes. More over, there
are many small improvements along the codebase and as always
we could not resist adding some cool new features.
Special thanks fly to Bryan Sotto for making this release
possible!
Most notable chages:
* Nitro allows fine grained customization of the compiler
tranformation pipeline per controller or even per action.
Here come some examples:
class MyController
ann :self, :transformation_pipeline => [MyTransformer, AnotherXForm]
...
def my_action
...
end
ann :my_action, :transformation_pipeline => Compiler.transformation_pipeline.dup.shift(CustomXForm)
...
end
* Nitro automates integration testing by means of the new
session VCR feature that allows for easy proxy based
functional testing. A typicall session goes like this:
Start your app with:
ruby run.rb --record myfile
Then use your web browser to 'perform' your testing session.
You can used multiple browsers, concurrent users and hit all
the pages in your app. At the end, just stop the server.
In order to perform regression testing against this recorded
session just restart the server in playback mode:
ruby run.rb --playback myfile
Nitro automatically plays back the recorded session and logs
any errors or Exceptions.
* Better Global variable implementation works better with
distributed stores (Drb, Memcached). Notice the new
Global.init and Global[:key].update { |v| } methods.
* Improved the Router implementation. One notable addition
is support for global router initialization:
Router.rules = [
{ :match => /~(.*)/, :controller => IdController, :action => :view, :params => [:name] }
]
* Cleaned up glue by removing files duplicating functionality
allready available in Facets. Moreover, we moved several
generally useful files and methods from Glue to Facets.
* Replaced the old RSSHelper with the new FeedHelper. The new
implementation provides support for RSS, Atom, OPML. The
FeedHelper is backwards compatible with the old helper but
provides even more features.
class MyController
helper :feed
end
* Added Og query by example support. Query the database for an
entity that matches the example. The example is a hash
populated with the property values to search for.
The provided property values are joined with AND to build
the actual query.
Article.query_by_example :title => 'IBM%', :hits => 2
Article.find_with_properties :title => 'IBM%', :hits => 2
* Added type casting support for Og aggregations and
calculations.
* Greatly improved the configuration system. One noteable
(and extremely useful) new feature is that you can now
customize classes before they are even defined:
Configuration.User.crypt_salt = 'HELLO'
require 'users'
in users.rb:
class User
setting :crypt_salt, :default => 'DF', :doc => 'The crypt salt'
end
* Calculate rendering level in actions to allow for conditional
rendering in top level actions or sub-actions. Some helpers
are also provided:
def myaction
if request.is_top_level?
...
end
end
* Introduced an alternative more sophisticated (yet intuitive)
form builder. While this new helper is still under construction,
it is already very useful. Here come some examples:
#{form :method => :multipart do |f|
f.p {
f.label 'Select the new icon filename'
f.select_file :file, :label => 'Select icon'
}
f.p {
f.submit 'Change'
}
end}
* More flexible Script generator, the developer can use most of
its features without a Client subclass.
* Reimplemented session garbage collection.
* Added many more RDoc comments to the source code.
* Many, many bug fixes.
* Updated to latest Facets, Scriptaculous, Prototype.
Please note that the project home page has been moved to:
http://www.nitroproject.org
== Version 0.29.0
A bold step towards maturity. Great care was taken to
fix reported bugs and fine tune many aspects of Nitro and Og.
As always some great new features where added. Special thanks fly
to Jonas Pfenniger, Bryan Sotto, Rob Pitt and Guillaume
Pierronnet for making this release possible.
Most notable changes:
* Greatly improved error detection and report. Nitro now provides
line exact error reports at compile or run time, in actions
or templates. Stay tuned for more improvements in error
handling.
* Nitro now supports a very useful url endoding/decoding system
along with a Camping inspired R operator. This new system allows
you to refer to controllers and actions in your code, without
bothering about the enforced nice urls and rewrite/routing
rules. This allows you to write more robust code.
Here are some examples:
redirect R(UsersController, :login, :name, 'gmosx')
delete
some more helpers and better integration of this feature
will be available soon.
* To better support the URL codec, a new router was implemented.
The new version is both more powerfull and faster. Here are
some examples:
r.add_route(%r{rewritten/url/(.*)}, :controller => IdController, :action => :register, :param => :name)
r.add_route(%r{another/zelo/(.*)/(.*)}, :controller => AdminController, :action => :kick, :params => [:name, :age])
r.add_route(%r{cool/(.*)_(.*).html}, :controller => AdminController, :action => :long, :params => [:name, :age])
* Og now supports calculations and aggregations. Here are some
examples:
User.min(:age)
User.average(:age)
User.maximum(:age)
User.min(:age, :group => :profession) # => [..] (aggregation)
User.sum(:age, :group => :role) # => [..]
and more!
* Improved template_root handling. Now Nitro automatically generates
a template_root stack for each controller / publishable object.
Of course the developer can fully customize this stack.
This is great for reusable modules of functionality (parts). Lets
say you have implemented a forum part. When you 'mount' the
forum controller a path relative to the mount point is pushed
in the template_root stack. When the dispatcher searches for
a template, it traverses the stack. In the described scenario
it first looks in the application template root, next in a template
root the points inside the part template root and then in the
proto dir template root. The proto dir template root is automatically
pushed as the last root in the stack. This system facilitates
'object oriented sites'.
Use the following method to customize the template_root.
def self.setup_template_root(path)
...
end
* Added support for JSP like application scoped (global)
variables.
def login
...
global[:users] << current_user
application[:users] << current_user
...
end
The global/application hash is backed by any of the available
cache stores.
* Improved Taggable mixin, now provides more helpers and supports
tag garbage collection through reference counting.
* Added a new store for the generalized caching system that is
backed by a MemCache server. Useful to extract the last ounch
of performance in a production environment.
* Fixes in the SCGI adapter.
* Many Og bug fixes and optimizations.
* More flexible static include compiler.
* Improved testing support.
* Integrated latest versions of Scriptaculous and Facets.
* Many, many bug fixes and small improvements throughout the
code.
== Version 0.28.0
A snapshot of the latest developments. As always, cool new
features were added, the code is refactored, the security increased
and reported bugs fixed.
Most notable changes:
* New generalized caching system. The caching code is refactored
in a new Glue system. At the moment, caches in memory, DRb,
filesystem and Og are provided. A memcache version will be available
in the near future. The new caching system is used to implement
Session stores, Og caching, Fragment caching, and Application scoped
parameters. A useful DRb cache management script is provided to
manage multiple DRb caches.
* Introduced a new Og Cacheable mixin. By including this mixin
in your classes you make them eligible to Og caching. Here comes
an example:
class User
is Cachable
property :name, String
property :age, Fixnum
end
Cacheable reuses the new generalized caching system to provide
various options for distributed caching. At the moment entities
(instances of managed classes) are cached by their primary key.
* Og now advanced quering using Ruby as the data query language
to complement the usage of Ruby as a data definition language
and provide an end-to-end Ruby solution. At the moment only
supported for the SQL based adapters. Here comes an example:
users = User.find do |user|
user.age > 10
user.any {
name == 'George'
name == 'Stella'
}
end
# => SELECT * FROM oguser WHERE (oguser.age > 10 AND (oguser.name = 'George' OR oguser.name = 'Stella'))
This feature uses the Caboose/EZ code by Ezra. Pure magic!
* Og find now supports prepared statement like syntax:
User.find :condition => ['name LIKE ? and create_time > ?', 'g%', Time.now]
The interpolated values are automatically escaped to avoid
SQL injection attacks.
Some additional forms of find are supported:
User.find [['name = ? and create_time > ?', 'gmosx', Time.now]
User.find "name = 'gmosx'"
and more.
* Added experimental support for deep copying (cloning) of Og
managed objects. This mechanism handles properties (annotated
attributes) and some relation types.
* Integration of Facets 1.0.1. The new library features a better
API and better implementation of various features.
* Introduced experimental Mongrel adapter, just use:
ruby myapp.rb --mongrel
* Fixes in the SCGI/FCGI adapters.
* Added schema evolution support to the SQLite adapter. All major
Og adapter support automatic schema evolution, ie Og detects common
types of changes in your Ruby code to automatically alter the
underlying schema for you.
* Introduced Og SQLite2 (legacy SQLite) adapter.
* Added more test cases, and improved RDoc comments throughout
the code.
* Many, many bug fixes.
== Version 0.27.0
Once again we have a great mix of cool new features, along
with bugfixes and a myriad of smaller improvements. Go and
download the most advanced Ruby Web/ORM Framework you can find.
Most notable changes:
* Added groundbreaking client side action/scripting support:
class FlickrDemo < Nitro::Controller
helper :javascript
class Client
# Actions defined here are executed as javescript in the
# browser.
def clear_me
hide :hide_me
end
def grab
ajax_upadate ...
end
end
end
in the template:
...
clear
the client element is converted to a javascript call that
executes the code in the client action. A domain specific
language is provided for the client action to implement stuff
like ajax async updates, scriptaculous visual fx and more.
* A collection of morphers to work along with client actions.
Here are some examples:
Drag me
in the controller:
def tags_auto_complete
%{
navel
nitro
sexy
}
end
More stuff is coming in future versions.
* Greatly imporoved the Elements system. The ElementMixin module
is auto-injected if missing. Nitro automatically transforms
xhtml template files in the Element.template_root into
Element classes for even better separation of code and design.
A simple Rails style layout helper is implememnted on top of
the general and powerful Elements mechanism for people familiar
with Rails.
* New WebFile system. Uploading files and handling photos was
never easier:
class Photo
is Timestamped
is Taggable
property :title, String
property :file, WebFile, :magick => { :small => '64x64', :medium => '128x128' }
end
# the upload action
def upload
photo = Photo.assign(request)
photo.save
end
This saves the photo, and creates 2 thumbnails. You can easily
access the photo and thumbnails like this:
ie obj.{propertyname}_#{thumbname}_thumbnail
* Og live collections support accumulation. Here is an example:
class Category
has_many :projects
end
class Project
has_many :clients
end
class Client
end
clients = category.projects.clients
# => returns all clients for this category!
* Improved TableHelper, better configurability, more skinnable,
sorting support and more.
* Added some intelligent auto-discovery features to minimize the
setup code. For example helpers are automatically loaded, and
the template_root is auto-discovered.
* Optimized the autoreloading system to only reload the dirty
files. In fact the new autoreloading system is so efficient
that it is enables by default even in live/production mode.
* Add Flickr, a great new example that shows off the new
javascript integration and AJAX features of Nitro.
* Added Gallery example to demonstrate the new WebFile
functionality.
* Improved the generated RDOC comments.
* Fixes in CGI adapter.
* Added evolution support to the KirbyBase adapter.
* Updated to scriptaculous 1.5.1
* Scaffolding - auto admin interface improvements.
* Added setup.rb for non-gem installation (experimental).
* Added ACGI adapter (experimental).
== Version 0.26.0
Another step closer to web programming nirvana. This release
features completely recoded scaffolding, an auto admin system,
a recoded template-morphing system, a new intelligent dispatcher
that handles both nice urls and general structure, and so much
more. Moreover, this is the release with the most community
contributions. Download now!
Most notable changes:
* New, intelligent dispatcher handles nice urls automatically,
without explicit rewrite rules. At the same time, it handles
sub directories, so you are free to design your app's
structure as you like.
* New template morphing implementation. The morphing compiler
is fully customizable. You can implement your own morphers and
add them to the morphing system, here for example is the
new selected_if morpher:
becomes
* New Sweeper mixin. Using this mixin allows you to keep
the cleanup logic in one place. This logic is called
automagically by many default Nitro/Og methods (for example
Og insert/update, scaffolding, etc). You can fully customize
the behaviour.
class Article
include Sweeper
def sweep_affected(action = :all)
expire_affected_output('articles/view')
...
end
end
a = Article[1]
a.title = 'New'
a.save # => calls expire_affected.
This mixin is typically used to automatically clean up output
caching files from the filesystem, but you can use it to remove
temp rows from the database, or temp objects from a drb server
or anything you like.
* Searchable mixin. Include this mixin to your classes to make
them searchable by the auto administration system.
* Added two new session managers (OgSession, FileSession),
cleaned up the session code.
* Better validations implementation. Cleaner code, less evals,
more flexible and easier to extend.
* New scaffolding / auto administration system. The implementation
is much cleaner and easier to customize. It leverages the latest
advancements (dispatcher, sweeper, etc) and adds search support,
pager, breadcrumps and more. You can define your own controls
to handle properties and relations. Stay tuned for more stuff
in the near future.
* New Og revisable mixin. Just include this mixin in your classes
and get db backed revision support for free. Here comes an
example:
class Article
is Revisable
property :body, String, :revisable => true
property :title, String
end
Automatically generates the Revision class (and the
backend schema):
class Article::Revision
article.revisions
article.revise do |a|
a.title = 'hello'
a.body = 'world'
end
article.rollback(4)
* Bug fixed KirbyBase Og adapter. This works great with the
new 2.5 gem.
* Added more rational defaults, and many predefined options to
minimize the amount of setup needed to get your app running. Of
course you can still customize just about everything in Nitro.
* Improvements to PostgreSQL automatic generation of foreign key
constraints.
* Added evolution support to the MySql store.
* Upgrated to Prototype 1.4 and Scriptaculous 1.5
* Updated the examples, check out the improved blog and why_wiki
examples.
* Many, many, many bug fixes and smaller improvements.
== Version 0.25.0
This is the first in a series of releases focused on stability
and refinement. Many bugs where fixed, the high level api was
improved where needed, and we still got some small but incredibly
useful new features. Enjoy!
Most notable changes:
* Support for constrained / scoped queries in Og, here are
some examples:
User.with_scope(:condition => 'age > 2') {
users = User.all
}
Users.articles.find "title LIKE %t%" # => constrain i users articles.
* Dynamic auto generators, you can now query the database in
English:
User.find_by_name_and_age('gmosx', 'age')
User.find_or_create_by_name_and_age(...)
* Added experimental version of a new schema evolution system. Assuming
evolve_schema = true and evolve_schema_cautious = false
* With this patch, on application startup, fields are added and deleted.
* During run-time, if the file containing Og.setup is touched, fields are added.
* Fields are _not_ deleted during run-time, only at application startup.
a the moment this works only in the PostgreSQL store, support for more
stores is coming in the next versions. Thanks to Rob Pitt and Bryan Sotto
for this feature.
* Template morphing now handles nested elements, an example: