subview

Created: 2008-12-06 05:05
Updated: 2016-05-08 18:38

README.markdown

subView

A next-gen template engine -- cause mixing ruby code and semantic html (via erb) SUCKS!!

erb was created in 1999, a 20th century technology. What is this Active Server Pages??

Ruby Template Framework for the 21st Century!

Philosophy

To keep html clean, simple, semantic, and separated from Ruby logic. The community focuses so much on separating css styles from html; javascript from html, then we stick a patch of logic poo, with Ruby, right in the html.

We are reducing cohesion through removing dependecy on locality, see Jim Weircach's talk: The Building Blocks of Modularity

Coopetition

There really is no other solution, in Ruby that follows through with this concept. Asp.net has a similiar concept with code behind pages, but is convoluted with a complex page callback cycle and squirlly callbacks, too complex.

Java and PHP have similiar ideas:

  • some examples

This does not compete with Haml at all, is actually complimentary and can help clean up Haml files. subView can work in tandem with Erb!


index.erb.html
index.rb

Existing Ruby Template Engines

  • Kwartz - Erb Version II by the same author as Erb, has the right concept, implementation is horrible
  • Erector - Pivotal Builder Crap
  • Punk - Initializing but adds tags to html
  • 19 Ruby Template Engines

Organization

A ruby file compliments a html file.

This could reside in the same directory or a separte /subview directory.


/products
   index.html
   index.rb
   new.html
   new.rb
   _fresh_jive.html
   _fresh_jive.rb

The SubView Class

class Index include SubView

end

Initialization

JOhn Doe

def initialize self.some_label.value = current_customer.name end

John Doe

label :some_label do |l| l.text = 'John Doe' end

Conditions

<% if @order.size > 0 %> -- order table --

<% else %> Sorry no orders exist <% end %>

def initialize @orders = Order.find(:all) if @orders.size < 0 self.('#order_table').hide() end end

table :order_table do |t| @orders = DeliveryOrders.find(:all) if @orders > 0 t.data = @orders else t.hide '#message'.show end end

  • actually removes from resulting html, not just turning off style

Forms

  • No more form helpers, set object and url in twin.
  • name in html can match object or not
Username

Password

this.session_form = Session this.session_form.action = new_session_path() this.session_form.login = Session.login this.session_form.password = Session.password

form :some_form do |f| customer = current_customer f.action = new_customer_path f.name = current_customer.first_name f.email = current_customer.email end

Beautiful Blocks

A generic box to encapsulate some text

def box(title = nil, *args, &block) options = args.extract_options! style = options[:style] ? " style = '#{options[:style]}'" : ''

b = "<div class="box"#{style}>#{box_label(title) if title}" e = ''

data = capture(&block) res = b + data + e concat(res, block.binding) end

<% box('Name:') do %> <%=h @some_object.name %> <% end %>

Collections

object_collection = Object.find(:all) object_collection.value = Object.boo

Partials/Includes

  • automatically includes ruby partial view if id has _partial

_products.html _products_view.rb

  • mini-ruby code snippet

  • html include type partial

  • has reference to the Page View it is included in! allowing no passing of variables

self.products.each do |product| self.product_name = product.name self.product_cost = currency_value(product.cost) end

Application Layout

in the SubView class you can specify your enclosing application layout

class ProductView include SubView

template :application

end

\layouts\application.html

Themes

Amazingly easy to build Themes.

All you need is standard HTML with the right set of css tags!

No code just switch out html files.

Header/Bundling

| parameters to controller are available in View or variables set | ideally use parameters

def initalize @product = Product.find(id) self.head.meta_tag = @product.title self.head.include_javascript = auto_link end

Hooking up to the Mighty Merb

Kernel::use_template_engine

use_template_engine :sub_view

Ajax Events

Creates the plumbing for handling presentation centric ajax calls.

By just having the event method defined, underlying jquery will be generated and along with Metal will create the routing to send it to your presentation class:

event :selector, :event => :onMouseOut do |e| # e is an event class to reference addresses = Address.find(:all) end

callback javascript with the e (Event) class allowing you to pass info and

intercept view

event :selector, :event => :onMouseOut, :call => 'javaScript' do |e| addresses = Address.find(:all) end

event :some_form, :event => :onSubmit do # a no-no go to RESTful controllers end

CSS3 Selectors

Support for all CSS3 selectors

http://www.w3.org/TR/css3-selectors/

Full Example

def Index include SubView

def initialize self.h1 = $('#h1'). @address = Address.find(:first) end

def click_h1

end

rack routes parameters (like merb formal dynamic parameters!!)

def push name='create'

end

div :some_div do |d| d.inner_html = 'blah-blah' $('label').text = 'test' end

div '#some_div .ul' do |d|

end

table :order_table do |t| orders = DeliveryOrders.find(:all) t.partial = render_partial 'orders', :data => orders end

form :some_form do |f| customer = current_customer f.action = new_customer_path f.name = current_customer.first_name f.email = current_customer.email end

label :first_name do |l| l.text = 'yo' end

event :selector, :event => :onMouseOut, :call => 'javaScript' do |e| addresses = Address.find(:all) end

event :some_form, :event => :onSubmit do # a no-no go to RESTful controllers end

end

Cookies help us deliver our services. By using our services, you agree to our use of cookies Learn more