This is a fixed and rebased version of the previous revision.
It also uses an updated version of the mustache gem which supports accessing nested attributes using the dot notation. The updated gem is temporarily accessible only from the testing repo: https://admin.fedoraproject.org/updates/rubygem-mustache-0.99.4-4.fc15 https://admin.fedoraproject.org/updates/rubygem-mustache-0.99.4-4.fc16 https://admin.fedoraproject.org/updates/rubygem-mustache-0.99.4-4.fc17 https://admin.fedoraproject.org/updates/rubygem-mustache-0.99.4-4.el6
From: Imre Farkas ifarkas@redhat.com
--- src/Gemfile | 1 + src/Gemfile.lock | 2 + src/config/application.rb | 1 + .../initializers/mustache_template_handler.rb | 43 ++++++++++++++++++++ 4 files changed, 47 insertions(+), 0 deletions(-) create mode 100644 src/config/initializers/mustache_template_handler.rb
diff --git a/src/Gemfile b/src/Gemfile index 2d8e8df..529d658 100644 --- a/src/Gemfile +++ b/src/Gemfile @@ -7,6 +7,7 @@ gem 'sqlite3', :require => 'sqlite3' gem 'deltacloud-client', :require => 'deltacloud' gem 'sass' gem 'haml' +gem 'mustache' gem 'will_paginate', '>= 3.0.pre1' gem 'nokogiri' gem 'simple-navigation' diff --git a/src/Gemfile.lock b/src/Gemfile.lock index 4137ff7..ef7ac01 100644 --- a/src/Gemfile.lock +++ b/src/Gemfile.lock @@ -81,6 +81,7 @@ GEM mime-types (~> 1.16) treetop (~> 1.4.8) mime-types (1.16) + mustache (0.99.4) nokogiri (1.5.0.beta.4) oauth (0.4.4) pg (0.11.0) @@ -172,6 +173,7 @@ DEPENDENCIES haml json launchy + mustache nokogiri oauth pg diff --git a/src/config/application.rb b/src/config/application.rb index d1c2a7b..7b0356f 100644 --- a/src/config/application.rb +++ b/src/config/application.rb @@ -30,6 +30,7 @@ else require 'deltacloud' require 'sass' require 'haml' + require 'mustache' require 'will_paginate' require 'nokogiri' require 'simple-navigation' diff --git a/src/config/initializers/mustache_template_handler.rb b/src/config/initializers/mustache_template_handler.rb new file mode 100644 index 0000000..b6c6fbc --- /dev/null +++ b/src/config/initializers/mustache_template_handler.rb @@ -0,0 +1,43 @@ +module MustacheTemplate + + class Handler + def self.erb_handler + @@erb_handler ||= ActionView::Template.registered_template_handler(:erb) + end + + def self.call(template) + compiled_erb_template = erb_handler.call(template).gsub(/'/, "\\'") + "MustacheTemplate::View.new(self, '#{compiled_erb_template}').render.html_safe" + end + end + + class View + def initialize(view_context, compiled_erb_template) + @view_context = view_context + @template_source = evaluate_rails_helpers(compiled_erb_template) + end + + def render + renderer = @view_context.instance_variable_get('@renderer') if @view_context.instance_variable_names.include?('@renderer') + options = renderer.instance_variable_get("@options") if renderer + + if options && options.include?(:mustache) + Mustache.render(@template_source, options[:mustache]).html_safe + else + @template_source.html_safe + end + end + + private + + def evaluate_rails_helpers(compiled_erb_template) + @view_context.instance_eval do + eval(compiled_erb_template) + end + end + end + + +end + +ActionView::Template.register_template_handler :mustache, MustacheTemplate::Handler
From: Imre Farkas ifarkas@redhat.com
--- src/app/views/layouts/application.html.haml | 1 + src/public/javascripts/mustache.min.js | 6 ++++++ 2 files changed, 7 insertions(+), 0 deletions(-) create mode 100644 src/public/javascripts/mustache.min.js
diff --git a/src/app/views/layouts/application.html.haml b/src/app/views/layouts/application.html.haml index e97f85b..a05dd38 100644 --- a/src/app/views/layouts/application.html.haml +++ b/src/app/views/layouts/application.html.haml @@ -29,6 +29,7 @@ = javascript_include_tag "jquery-1.6.1.min.js" = javascript_include_tag "jquery.ui-1.8.1/jquery-ui-1.8.1.custom.min.js" = javascript_include_tag "jquery.tmpl.min.js" + = javascript_include_tag "mustache.min.js" = javascript_include_tag "underscore-min.js" = javascript_include_tag "backbone-min.js"
diff --git a/src/public/javascripts/mustache.min.js b/src/public/javascripts/mustache.min.js new file mode 100644 index 0000000..8014bcf --- /dev/null +++ b/src/public/javascripts/mustache.min.js @@ -0,0 +1,6 @@ +/*! Version: 0.4.2 */ +/* + mustache.js — Logic-less templates in JavaScript + + See http://mustache.github.com/ for more info. +*/var Mustache=function(){function g(a){return String(a).replace(/&(?!#?\w+;)|[<>"']/g,function(a){return f[a]||a})}var a=Object.prototype.toString;Array.isArray=Array.isArray||function(b){return a.call(b)=="[object Array]"};var b=String.prototype.trim,c;if(b)c=function(a){return a==null?"":b.call(a)};else{var d,e;/\S/.test(" ")?(d=/^[\s\xA0]+/,e=/[\s\xA0]+$/):(d=/^\s+/,e=/\s+$/),c=function(a){return a==null?"":a.toString().replace(d,"").replace(e,"")}}var f={"&":"&","<":"<",">":">",'"':""","'":"'"},h={},i=function(){};return i.prototype={otag:"{{",ctag:"}}",pragmas:{},buffer:[],pragmas_implemented:{"IMPLICIT-ITERATOR":!0},context:{},render:function(a,b,c,d){d||(this.context=b,this.buffer=[]);if(!this.includes("",a)){if(d)return a;this.send(a);return}a=this.render_pragmas(a);var e=this.render_section(a,b,c);e===!1&&(e=this.render_tags(a,b,c,d));if(d)return e;this.sendLines(e)},send:function(a){a!==""&&this.buffer.push(a)},sendLines:function(a){if(a){var ! b=a.split("\n");for(var c=0;c<b.length;c++)this.send(b[c])}},render_pragmas:function(a){if(!this.includes("%",a))return a;var b=this,c=this.getCachedRegex("render_pragmas",function(a,b){return new RegExp(a+"%([\w-]+) ?([\w]+=[\w]+)?"+b,"g")});return a.replace(c,function(a,c,d){if(!b.pragmas_implemented[c])throw{message:"This implementation of mustache doesn't understand the '"+c+"' pragma"};b.pragmas[c]={};if(d){var e=d.split("=");b.pragmas[c][e[0]]=e[1]}return""})},render_partial:function(a,b,d){a=c(a);if(!d||d[a]===undefined)throw{message:"unknown_partial '"+a+"'"};return!b||typeof b[a]!="object"?this.render(d[a],b,d,!0):this.render(d[a],b[a],d,!0)},render_section:function(a,b,c){if(!this.includes("#",a)&&!this.includes("^",a))return!1;var d=this,e=this.getCachedRegex("render_section",function(a,b){return new RegExp("^([\s\S]*?)"+a+"(\^|\#)\s*(.+?)\s*"+b+"\n*([\s\S]*?)"+a+"\/\s*\3\s*"+b+"\s*([\s\S]*)$","g")});return a.replace(e,function(a,e,f,g,h,i){var ! j=e?d.render_tags(e,b,c,!0):"",k=i?d.render(i,b,c,!0):"",l,m=d.find(g,b);return f==="^"?!m||Array.isArray(m)&&m.length===0?l=d.render(h,b,c,!0):l="":f==="#"&&(Array.isArray(m)?l=d.map(m,function(a){return d.render(h,d.create_context(a),c,!0)}).join(""):d.is_object(m)?l=d.render(h,d.create_context(m),c,!0):typeof m=="function"?l=m.call(b,h,function(a){return d.render(a,b,c,!0)}):m?l=d.render(h,b,c,!0):l=""),j+l+k})},render_tags:function(a,b,c,d){var e=this,f=function(){return e.getCachedRegex("render_tags",function(a,b){return new RegExp(a+"(=|!|>|&|\{|%)?([^#\^]+?)\1?"+b+"+","g")})},h=f(),i=function(a,d,i){switch(d){case"!":return"";case"=":return e.set_delimiters(i),h=f(),"";case">":return e.render_partial(i,b,c);case"{":case"&":return e.find(i,b);default:return g(e.find(i,b))}},j=a.split("\n");for(var k=0;k<j.length;k++)j[k]=j[k].replace(h,i,this),d||this.send(j[k]);if(d)return j.join("\n")},set_delimiters:function(a){var b=a.split(" ");this.otag=this.escape_regex(b[0]! ),this.ctag=this.escape_regex(b[1])},escape_regex:function(a){if(!argum! ents.callee.sRE){var b=["/",".","*","+","?","|","(",")","[","]","{","}","\"];arguments.callee.sRE=new RegExp("(\"+b.join("|\")+")","g")}return a.replace(arguments.callee.sRE,"\$1")},find:function(a,b){function d(a){return a===!1||a===0||a}a=c(a);var e;if(a.match(/([a-z_]+)./ig)){var f=this.walk_context(a,b);d(f)&&(e=f)}else d(b[a])?e=b[a]:d(this.context[a])&&(e=this.context[a]);return typeof e=="function"?e.apply(b):e!==undefined?e:""},walk_context:function(a,b){var c=a.split("."),d=b[c[0]]!=undefined?b:this.context,e=d[c.shift()];while(e!=undefined&&c.length>0)d=e,e=e[c.shift()];return typeof e=="function"?e.apply(d):e},includes:function(a,b){return b.indexOf(this.otag+a)!=-1},create_context:function(a){if(this.is_object(a))return a;var b=".";this.pragmas["IMPLICIT-ITERATOR"]&&(b=this.pragmas["IMPLICIT-ITERATOR"].iterator);var c={};return c[b]=a,c},is_object:function(a){return a&&typeof a=="object"},map:function(a,b){if(typeof a.map=="function")return a.map(b);var c=[! ],d=a.length;for(var e=0;e<d;e++)c.push(b(a[e]));return c},getCachedRegex:function(a,b){var c=h[this.otag];c||(c=h[this.otag]={});var d=c[this.ctag];d||(d=c[this.ctag]={});var e=d[a];return e||(e=d[a]=b(this.otag,this.ctag)),e}},{name:"mustache.js",version:"0.4.2",to_html:function(a,b,c,d){var e=new i;d&&(e.send=d),e.render(a,b||{},c);if(!d)return e.buffer.join("\n")}}}(); \ No newline at end of file
From: Imre Farkas ifarkas@redhat.com
--- src/app/controllers/instances_controller.rb | 2 +- src/app/helpers/application_helper.rb | 3 + src/app/helpers/mustache_helper.rb | 38 ++++++++++ .../views/deployments/_pretty_view_show.html.haml | 78 +------------------- .../views/instances/_instance_card.html.mustache | 58 +++++++++++++++ src/public/javascripts/backbone/views.js | 10 ++- 6 files changed, 112 insertions(+), 77 deletions(-) create mode 100644 src/app/helpers/mustache_helper.rb create mode 100644 src/app/views/deployments/_deployment_card.html.mustache create mode 100644 src/app/views/instances/_instance_card.html.mustache
diff --git a/src/app/controllers/instances_controller.rb b/src/app/controllers/instances_controller.rb index 7773d81..014b5a4 100644 --- a/src/app/controllers/instances_controller.rb +++ b/src/app/controllers/instances_controller.rb @@ -28,7 +28,7 @@ class InstancesController < ApplicationController respond_to do |format| format.html format.js { render :partial => 'list' } - format.json { render :json => @instances } + format.json { render :json => @instances.map{ |instance| view_context.instance_for_mustache(instance) } } end end
diff --git a/src/app/helpers/application_helper.rb b/src/app/helpers/application_helper.rb index 3443038..b74a341 100644 --- a/src/app/helpers/application_helper.rb +++ b/src/app/helpers/application_helper.rb @@ -18,6 +18,9 @@ # Likewise, all the methods added will be available for all controllers.
module ApplicationHelper + + include MustacheHelper + def number_to_duration(input_num) input_int = input_num.to_i hours_to_seconds = [input_int/3600 % 24, diff --git a/src/app/helpers/mustache_helper.rb b/src/app/helpers/mustache_helper.rb new file mode 100644 index 0000000..086caf5 --- /dev/null +++ b/src/app/helpers/mustache_helper.rb @@ -0,0 +1,38 @@ +# +# Copyright 2012 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Filters added to this controller apply to all controllers in the application. +# Likewise, all the methods added will be available for all controllers. + +module MustacheHelper + + def instance_for_mustache(instance) + available_actions = instance.get_action_list + + { + :id => instance.id, + :name => instance.name, + :path => instance_path(instance), + :uptime => count_uptime(instance.uptime), + :translated_state => t("instances.states.#{instance.state}"), + :public_addresses => instance.public_addresses.present? ? instance.public_addresses : I18n.t('deployments.pretty_view_show.no_ip_address'), + :instance_key_present => instance.instance_key.present?, + :stop_enabled => available_actions.include?(InstanceTask::ACTION_STOP), + :reboot_enabled => available_actions.include?(InstanceTask::ACTION_REBOOT), + } + end + +end diff --git a/src/app/views/deployments/_deployment_card.html.mustache b/src/app/views/deployments/_deployment_card.html.mustache new file mode 100644 index 0000000..e69de29 diff --git a/src/app/views/deployments/_pretty_view_show.html.haml b/src/app/views/deployments/_pretty_view_show.html.haml index c354ca9..696fd38 100644 --- a/src/app/views/deployments/_pretty_view_show.html.haml +++ b/src/app/views/deployments/_pretty_view_show.html.haml @@ -1,30 +1,6 @@ %ul.instances-array - @instances.each do |instance| - %li.instance - %h3.name - = link_to instance.name, instance - %hr - %dl.statistics - %ul - %li - %dt.uptime - %dd= count_uptime(instance.uptime) - %li - %dt.ip_address= t('deployments.pretty_view_show.ip_address') - %dd= instance.public_addresses.present? ? instance.public_addresses : t('deployments.pretty_view_show.no_ip_address') - %li - %dt.state= t('deployments.pretty_view_show.state') - %dd= t("instances.states.#{instance.state}") - - if instance.instance_key - %li - %dt - %dd= link_to t('deployments.pretty_view_show.download_key'), key_instance_path(instance) - %hr - .actions - %ul - - available_actions = instance.get_action_list - %li= button_to(t('deployments.pretty_view_show.stop'), stop_instance_path(instance), :disabled => !available_actions.include?(InstanceTask::ACTION_STOP), :class => "button danger") - %li= button_to(t('deployments.pretty_view_show.reboot'), reboot_instance_path(instance), :disabled => !available_actions.include?(InstanceTask::ACTION_REBOOT), :class => "button danger") + = render :partial => 'instances/instance_card', :mustache => instance_for_mustache(instance)
= render_pagination(@instances)
@@ -33,53 +9,5 @@ '#{url_for(:action => :show, :details_tab => 'instances', :view => 'filter', :page => params[:page])}', '#{url_for(:action => :show, :details_tab => 'instances', :view => 'pretty', :page => params[:page])}');
-%script#instanceTemplate{:type => 'text/x-jquery-tmpl'} - :plain - <li class="instance"> - <h3 class="name"><a href="#{instance_path('replace_id').sub('replace_id', '${id}')}">${name}</a></h3> - <hr> - <dl class="statistics"> - <ul> - <li> - <dt class="uptime"></dt> - <dd> ${uptime}</dd> - </li> - <li> - <dt class="ip_address">#{t('deployments.pretty_view_show.ip_address')}</dt> - <dd> - {{if public_addresses}} - ${public_addresses} - {{else}} - #{t('deployments.pretty_view_show.no_ip_address')} - {{/if}} - </dd> - </li> - <li> - <dt class="state">#{t('deployments.pretty_view_show.state')}</dt> - <dd>${translated_state}</dd> - </li> - {{if has_key}} - <li> - <dt/> - <dd><a href="#{key_instance_path('replace_id').sub('replace_id', '${id}')}">#{t('deployments.pretty_view_show.download_key')}</a></dd> - </li> - {{/if}} - </ul> - </dl> - <hr> - <div class="actions"> - <ul> - {{if stop_enabled}} - <li>#{button_to(t('deployments.pretty_view_show.stop'), stop_instance_path('replace_id').sub('replace_id', '${id}'), :disabled => false, :class => 'button danger')}</li> - {{else}} - <li>#{button_to(t('deployments.pretty_view_show.stop'), stop_instance_path('replace_id').sub('replace_id', '${id}'), :disabled => true, :class => 'button danger')}</li> - {{/if}} - - {{if reboot_enabled}} - <li>#{button_to(t('deployments.pretty_view_show.reboot'), reboot_instance_path('replace_id').sub('replace_id', '${id}'), :disabled => false, :class => 'button danger')}</li> - {{else}} - <li>#{button_to(t('deployments.pretty_view_show.reboot'), reboot_instance_path('replace_id').sub('replace_id', '${id}'), :disabled => true, :class => 'button danger')}</li> - {{/if}} - </ul> - </div> - </li> +%script#instanceCardTemplate{ :type => 'text/html' } + = render :partial => 'instances/instance_card' diff --git a/src/app/views/instances/_instance_card.html.mustache b/src/app/views/instances/_instance_card.html.mustache new file mode 100644 index 0000000..1cb651b --- /dev/null +++ b/src/app/views/instances/_instance_card.html.mustache @@ -0,0 +1,58 @@ +<li class="instance"> + <h3 class="name"> + <%= link_to('{{name}}', '{{path}}') %> + </h3> + <hr> + <dl class="statistics"> + <ul> + <li> + <dt class="uptime"></dt> + <dd>{{uptime}}</dd> + </li> + <li> + <dt class="ip_address"><%= t('deployments.pretty_view_show.ip_address') %></dt> + <dd>{{public_addresses}}</dd> + </li> + <li> + <dt class="state"><%= t('deployments.pretty_view_show.state') %></dt> + <dd>{{translated_state}}</dd> + </li> + {{#instance_key_present}} + <li> + <dt></dt> + <dd><%= link_to(t('deployments.pretty_view_show.download_key'), key_instance_path('replace_id').sub('replace_id', '{{id}}')) %></dd> + </li> + {{/instance_key_present}} + </ul> + </dl> + <hr> + <div class="actions"> + <ul> + {{#stop_enabled}} + <li> + <%= button_to(t('deployments.pretty_view_show.stop'), stop_instance_path('replace_id').sub('replace_id', '{{id}}'), + :disabled => false, :class => 'button danger') %> + </li> + {{/stop_enabled}} + {{^stop_enabled}} + <li> + <%= button_to(t('deployments.pretty_view_show.stop'), stop_instance_path('replace_id').sub('replace_id', '{{id}}'), + :disabled => true, :class => 'button danger') %> + </li> + {{/stop_enabled}} + + {{#reboot_enabled}} + <li> + <%= button_to(t('deployments.pretty_view_show.reboot'), reboot_instance_path('replace_id').sub('replace_id', '{{id}}'), + :disabled => false, :class => 'button danger') %> + </li> + {{/reboot_enabled}} + {{^reboot_enabled}} + <li> + <%= button_to(t('deployments.pretty_view_show.reboot'), reboot_instance_path('replace_id').sub('replace_id', '{{id}}'), + :disabled => true, :class => 'button danger') %> + </li> + {{/reboot_enabled}} + </ul> + </div> +</li> diff --git a/src/public/javascripts/backbone/views.js b/src/public/javascripts/backbone/views.js index a28bb1f..4c956ca 100644 --- a/src/public/javascripts/backbone/views.js +++ b/src/public/javascripts/backbone/views.js @@ -211,6 +211,9 @@ Conductor.Views.DeploymentsShow = Backbone.View.extend({ },
render: function() { + $template = $('#instanceCardTemplate'); + if($template.length === 0) return; + var $instances = this.$('ul.instances-array'); if($instances.length === 0) { $instances = this.$('table.checkbox_table > tbody'); @@ -218,7 +221,12 @@ Conductor.Views.DeploymentsShow = Backbone.View.extend({ if($instances.length === 0) return;
$instances.empty(); - $('#instanceTemplate').tmpl(this.collection.toJSON()).appendTo($instances); + + var instanceCardsHtml = ''; + $.each(this.collection.toJSON(), function(instanceIndex, instance) { + instanceCardsHtml += Mustache.to_html($template.html(), instance); + }); + $instances.html(instanceCardsHtml); }
});
From: Imre Farkas ifarkas@redhat.com
--- src/app/controllers/pools_controller.rb | 6 ++- src/app/helpers/mustache_helper.rb | 17 +++++++ src/app/models/pool.rb | 6 -- .../deployments/_deployment_card.html.mustache | 33 +++++++++++++ src/app/views/deployments/_pretty_view.html.haml | 50 +------------------ src/public/javascripts/backbone/views.js | 27 ++++++++++- 6 files changed, 82 insertions(+), 57 deletions(-)
diff --git a/src/app/controllers/pools_controller.rb b/src/app/controllers/pools_controller.rb index abc3203..2ae502a 100644 --- a/src/app/controllers/pools_controller.rb +++ b/src/app/controllers/pools_controller.rb @@ -117,8 +117,10 @@ class PoolsController < ApplicationController respond_to do |format| format.html { render :action => :show} format.js { render :partial => @view } - format.json { render :json => @pool.as_json(:with_deployments => true, :current_user => current_user, - :page => params[:page], :per_page => PER_PAGE) } + format.json { render :json => { :name => @pool.name, + :deployments => @pool.deployments.list_for_user(current_user, Privilege::VIEW). + paginate(:page => params[:page], :per_page => params[:per_page]). + map{ |deployment| view_context.deployment_for_mustache(deployment) } } } end end
diff --git a/src/app/helpers/mustache_helper.rb b/src/app/helpers/mustache_helper.rb index 086caf5..6131909 100644 --- a/src/app/helpers/mustache_helper.rb +++ b/src/app/helpers/mustache_helper.rb @@ -35,4 +35,21 @@ module MustacheHelper } end
+ def deployment_for_mustache(deployment) + { + :name => deployment.name, + :path => deployment_path(deployment), + :status => deployment.status, + :translated_state => I18n.t("deployments.status.#{deployment.status}"), + :uptime => count_uptime(deployment.uptime_1st_instance), + :instances_count => deployment.instances.count, + :instances_count_text => I18n.t('instances.instances', :count => deployment.instances.count.to_i), + :provider => { + :provider_type => { + :name => deployment.provider.present? ? deployment.provider.provider_type.name : nil, + } + } + } + end + end diff --git a/src/app/models/pool.rb b/src/app/models/pool.rb index 9556dee..4604bd2 100644 --- a/src/app/models/pool.rb +++ b/src/app/models/pool.rb @@ -137,12 +137,6 @@ class Pool < ActiveRecord::Base
})
- if options[:with_deployments] - result[:deployments] = deployments.list_for_user(options[:current_user], Privilege::VIEW). - paginate(:page => options[:page], :per_page => options[:per_page]). - map {|d| d.as_json} - end - result end
diff --git a/src/app/views/deployments/_deployment_card.html.mustache b/src/app/views/deployments/_deployment_card.html.mustache index e69de29..f7b0926 100644 --- a/src/app/views/deployments/_deployment_card.html.mustache +++ b/src/app/views/deployments/_deployment_card.html.mustache @@ -0,0 +1,33 @@ +<li class="deployment"> + <h3 class="name"> + <%= link_to('{{name}}', '{{path}}') %> + </h3> + <span title="{{translated_state}}" class="status {{status}}">alma</span> + <dl class="statistics"> + <ul> + <li class="uptime"> + <dt class="uptime"><%= t('uptime') %></dt> + <dd>{{uptime}}</dd> + </li> + <li class="instances"> + <dt class="instances count"><%= t('instances.instances.other') %></dt> + <dd> + {{instances_count}} + <span class="inline-label">{{instances_count_text}}</span> + </dd> + </li> + <li class="provider"> + <dt class="instances count"><%= t('providers.provider') %></dt> + <dd> + <p class="provider"> + {{#provider}} + {{#provider_type}} + {{name}} + {{/provider_type}} + {{/provider}} + </p> + </dd> + </li> + </ul> + </dl> +</li> diff --git a/src/app/views/deployments/_pretty_view.html.haml b/src/app/views/deployments/_pretty_view.html.haml index 12f8d00..2f5e6f7 100644 --- a/src/app/views/deployments/_pretty_view.html.haml +++ b/src/app/views/deployments/_pretty_view.html.haml @@ -2,25 +2,7 @@ - @deployments.in_groups_of(5, false) do |group| %ul.deployment-array.large - group.each do |deployment| - - deployment_provider = deployment.provider - %li.deployment - %h3.name - = link_to deployment.name, deployment_path(deployment) - %span{ :class => "status #{deployment.status}", :title => t("deployments.status.#{deployment.status}")} - %dl.statistics - %ul - %li.uptime - %dt.uptime=t'uptime' - %dd= count_uptime(deployment.uptime_1st_instance) - %li.instances - %dt.instances.count=t'instances.instances.other' - %dd - = deployment.instances.count || 0 - %span.inline-label=t('instances.instances', :count => deployment.instances.count.to_i) - %li.provider - %dt.instances.count=t'providers.provider' - %dd - %p.provider= deployment_provider.provider_type.name unless deployment_provider.blank? + = render :partial => 'deployments/deployment_card', :mustache => deployment_for_mustache(deployment)
= render_pagination(@deployments)
@@ -29,31 +11,5 @@ '#{url_for(:action => :show, :details_tab => 'deployments', :view => 'filter', :page => params[:page])}', '#{url_for(:action => :show, :details_tab => 'deployments', :view => 'pretty', :page => params[:page] )}');
-%script#deploymentTemplate{ :type => 'text/x-jquery-tmpl' } - :plain - <li class="deployment"> - <h3 class="name"> - <a href="#{deployment_path('replace_id').sub('replace_id', '${id}')}">${name}</a> - </h3> - <span class="status ${status}" title="${status_description}">${status}</span> - <dl class="statistics"> - <ul> - <li class="uptime"> - <dt class="uptime">#{t'uptime'}</dt> - <dd>${uptime}</dd> - </li> - <li class="instances"> - <dt class="instances count">#{t'instances.instances.other'}</dt> - <dd>${instances_count} - <span class="inline-label">${instances_count_text}</span> - </dd> - </li> - <li class="provider"> - <dt class="instances count">#{t'providers.provider'}</dt> - <dd> - <p class="provider">{{if provider}} ${provider.name} {{/if}}</p> - </dd> - </li> - </ul> - </dl> - </li> +%script#deploymentCardTemplate{ :type => 'text/html' } + = render :partial => 'deployments/deployment_card' diff --git a/src/public/javascripts/backbone/views.js b/src/public/javascripts/backbone/views.js index 4c956ca..876ad9b 100644 --- a/src/public/javascripts/backbone/views.js +++ b/src/public/javascripts/backbone/views.js @@ -101,6 +101,15 @@ Conductor.Views.PoolsIndex = Backbone.View.extend({ Conductor.Views.PoolsShow = Backbone.View.extend({ el: '#content',
+ currentView: function() { + if ($('form.filterable-data').length > 0) { + return 'table' + } + else if ($('ul.deployable-cards').length > 0) { + return 'pretty' + } + }, + currentTab: function() { if($('#details_deployments.active').length > 0) { return 'deployments'; @@ -113,6 +122,15 @@ Conductor.Views.PoolsShow = Backbone.View.extend({ } },
+ template: function() { + if (this.currentView() == 'table') { + return $('#deploymentTemplate'); + } + else if (this.currentView() == 'pretty') { + return $('#deploymentCardTemplate'); + } + }, + queryParams: function() { var paramsToInclude = ['deployments_preset_filter', 'deployments_search', 'page']; var result = Conductor.extractQueryParams(paramsToInclude); @@ -132,7 +150,7 @@ Conductor.Views.PoolsShow = Backbone.View.extend({ render: function() { this.$('h1.pools').text(this.model.get('name') + ' Pool');
- var $template = $('#deploymentTemplate'); + var $template = this.template(); if($template.length === 0) return;
var $table = this.$('table.checkbox_table > tbody'); @@ -146,9 +164,14 @@ Conductor.Views.PoolsShow = Backbone.View.extend({ var $cards = this.$('ul.deployable-cards').empty() var cardsPerRow = 5; for(var i = 0; i < deployments.length; i += cardsPerRow) { + var deploymentCardHtml = ''; + $.each(deployments.slice(i, i + cardsPerRow), function(deploymentIndex, deployment) { + deploymentCardHtml += Mustache.to_html($template.html(), deployment); + }); + var $row = this.make('ul', {'class': 'deployment-array large'}, - $template.tmpl(deployments.slice(i, i + cardsPerRow))); + deploymentCardHtml); $cards.append($row); } }
From: Imre Farkas ifarkas@redhat.com
--- src/app/helpers/mustache_helper.rb | 15 ++++++- .../deployments/_deployment_row.html.mustache | 28 ++++++++++++ src/app/views/deployments/_list.html.haml | 46 ++++---------------- src/public/javascripts/backbone/views.js | 17 ++++++- 4 files changed, 64 insertions(+), 42 deletions(-) create mode 100644 src/app/views/deployments/_deployment_row.html.mustache
diff --git a/src/app/helpers/mustache_helper.rb b/src/app/helpers/mustache_helper.rb index 6131909..60cc9a1 100644 --- a/src/app/helpers/mustache_helper.rb +++ b/src/app/helpers/mustache_helper.rb @@ -37,17 +37,28 @@ module MustacheHelper
def deployment_for_mustache(deployment) { + :id => deployment.id, :name => deployment.name, :path => deployment_path(deployment), + :filter_view_path => deployment_path(deployment, :view => :filter), :status => deployment.status, :translated_state => I18n.t("deployments.status.#{deployment.status}"), :uptime => count_uptime(deployment.uptime_1st_instance), + :deployable_xml_name => deployment.deployable_xml.name, + :created_at => deployment.created_at.to_s, :instances_count => deployment.instances.count, :instances_count_text => I18n.t('instances.instances', :count => deployment.instances.count.to_i), + :owner => deployment.owner.present? ? deployment.owner.name : nil, + :failed_instances_present => deployment.failed_instances.count > 0, :provider => { + :path => deployment.provider.present? ? provider_path(deployment.provider) : nil, :provider_type => { - :name => deployment.provider.present? ? deployment.provider.provider_type.name : nil, - } + :name => deployment.provider.present? ? deployment.provider.provider_type.name : nil, + } + }, + :pool => { + :name => deployment.pool.name, + :filter_view_path => pool_path(deployment.pool, :view => :filter), } } end diff --git a/src/app/views/deployments/_deployment_row.html.mustache b/src/app/views/deployments/_deployment_row.html.mustache new file mode 100644 index 0000000..34dfa26 --- /dev/null +++ b/src/app/views/deployments/_deployment_row.html.mustache @@ -0,0 +1,28 @@ +<tr> + <td class="checkbox"> + <%= check_box_tag("deployments_selected[]", '{{id}}', false, :id => "deployment_checkbox_{{id}}") %> + </td> + <td class="alert"> + {{#failed_instances_present}} + <%= image_tag("sb_icon_instance_failure.png") %> + {{/failed_instances_present}} + </td> + <td> + <%= link_to('{{name}}', '{{filter_view_path}}') %> + </td> + <td>{{created_at}}</td> + <td>{{deployable_xml_name}}</td> + <td>{{translated_state}}</td> + <td class="center">{{instances_count}}</td> + <td> + {{#pool}} + <%= link_to('{{name}}', '{{filter_view_path}}') %> + {{/pool}} + </td> + <td>{{owner}}</td> + <td> + {{#provider}} + <%= link_to('{{provider_type.name}}', '{{path}}') %> + {{/provider}} + </td> +</tr> diff --git a/src/app/views/deployments/_list.html.haml b/src/app/views/deployments/_list.html.haml index 308a98d..c1ee53b 100644 --- a/src/app/views/deployments/_list.html.haml +++ b/src/app/views/deployments/_list.html.haml @@ -27,20 +27,7 @@ });
= filter_table(@deployments_header, @deployments) do |deployment| - - deployment_provider = deployment.provider - %tr{ :class => cycle('nostripe', 'stripe') } - %td{:class => 'checkbox'} - - selected = params[:select] == 'all' - = check_box_tag "deployments_selected[]", deployment.id, selected, :id => "deployment_checkbox_#{deployment.id}" - %td{:class => 'alert'}= deployment.failed_instances.present? ? image_tag("sb_icon_instance_failure.png") : "" - %td= link_to(deployment.name, deployment_path(deployment, :view => :filter)) - %td= deployment.created_at - %td= deployment.deployable_xml.name - %td= t("instances.states.#{deployment.status}") - %td{:class => 'center'}= deployment.instances.size - %td= link_to deployment.pool.name, pool_path(deployment.pool, :view => :filter) - %td= owner_name(deployment) - %td= link_to(deployment_provider.provider_type.name, deployment_provider) if deployment_provider + = render :partial => 'deployments/deployment_row', :mustache => deployment_for_mustache(deployment)
:javascript Conductor.setupPrettyFilterURL( @@ -48,26 +35,11 @@ '#{url_for(:action => :show, :details_tab => 'deployments', :view => 'pretty', :page => params[:page])}' );
-%script#deploymentTemplate{ :type => 'text/x-jquery-tmpl' } - :plain - <tr> - <td class="checkbox"><input type="checkbox" id="deployment_checkbox_${id}" - name="deployments_selected[]" value="${id}"></td> - <td class="alert"> - {{if failed_instances_count > 0}} - #{image_tag("sb_icon_instance_failure.png")} - {{/if}} - </td> - <td><a href="#{deployment_path('replace_id', :view => :filter).sub('replace_id', '${id}')}">${name}</a></td> - <td>${created_at}</td> - <td>${deployable_xml_name}</td> - <td>${translated_status}</td> - <td class="center">${instances_count}</td> - <td><a href="#{pool_path('replace_id', :view => :filter).sub('replace_id', '${pool.id}')}">${pool.name}</a></td> - <td>${owner}</td> - <td> - {{if provider}} - <a href="#{provider_path('replace_id').sub('replace_id', '${provider.id}')}">${provider.name}</a> - {{/if}} - </td> - </tr> +:javascript + $(document).ready(function(){ + $('tr:odd').addClass('stripe'); + $('tr:even').addClass('nostripe'); + }); + +%script#deploymentRowTemplate{ :type => 'text/html' } + = render :partial => 'deployments/deployment_row' diff --git a/src/public/javascripts/backbone/views.js b/src/public/javascripts/backbone/views.js index 876ad9b..0d29417 100644 --- a/src/public/javascripts/backbone/views.js +++ b/src/public/javascripts/backbone/views.js @@ -124,7 +124,7 @@ Conductor.Views.PoolsShow = Backbone.View.extend({
template: function() { if (this.currentView() == 'table') { - return $('#deploymentTemplate'); + return $('#deploymentRowTemplate'); } else if (this.currentView() == 'pretty') { return $('#deploymentCardTemplate'); @@ -155,9 +155,20 @@ Conductor.Views.PoolsShow = Backbone.View.extend({
var $table = this.$('table.checkbox_table > tbody'); var deployments = this.model.get('deployments'); - if($table.length !== 0) { + if(this.currentView() == 'table') { var checkboxes = Conductor.saveCheckboxes('td :checkbox', $table); - $table.empty().append($template.tmpl(deployments)) + + var deplyomentRowsHtml = ''; + $.each(deployments, function(deploymentIndex, deployment) { + deplyomentRowsHtml += Mustache.to_html($template.html(), deployment); + }); + + $table.empty().append(deplyomentRowsHtml); + Conductor.restoreCheckboxes(checkboxes, 'td :checkbox', $table); + + $('tr:odd').addClass('stripe'); + $('tr:even').addClass('nostripe'); + Conductor.restoreCheckboxes(checkboxes, 'td :checkbox', $table); } else {
From: Imre Farkas ifarkas@redhat.com
--- src/app/controllers/pools_controller.rb | 4 +- src/app/helpers/mustache_helper.rb | 26 ++++++++++++++++ src/app/views/pools/_list.html.haml | 43 ++++++-------------------- src/app/views/pools/_pool_row.html.mustache | 26 ++++++++++++++++ src/public/javascripts/backbone/views.js | 12 +++++-- 5 files changed, 73 insertions(+), 38 deletions(-) create mode 100644 src/app/views/pools/_pool_row.html.mustache
diff --git a/src/app/controllers/pools_controller.rb b/src/app/controllers/pools_controller.rb index 2ae502a..4a3a9d8 100644 --- a/src/app/controllers/pools_controller.rb +++ b/src/app/controllers/pools_controller.rb @@ -78,11 +78,11 @@ class PoolsController < ApplicationController format.json do case @details_tab[:id] when 'pools' - render :json => @pools + render :json => @pools.map{ |pool| view_context.pool_for_mustache(pool) } when 'instances' render :json => @instances when 'deployments' - render :json => @deployments + render :json => @deployments.map{ |deployment| view_context.deployment_for_mustache(deployment) } end end end diff --git a/src/app/helpers/mustache_helper.rb b/src/app/helpers/mustache_helper.rb index 60cc9a1..b13ef67 100644 --- a/src/app/helpers/mustache_helper.rb +++ b/src/app/helpers/mustache_helper.rb @@ -63,4 +63,30 @@ module MustacheHelper } end
+ def pool_for_mustache(pool) + pool_statistics = pool.statistics + user_can_access_pool_family = check_privilege(Privilege::VIEW, pool.pool_family) + + { + :id => pool.id, + :name => pool.name, + :filter_view_path => pool_path(pool, :view => :filter), + :failed_instances_present => pool_statistics[:instances_failed_count] > 0, + :deployments_count => pool.deployments.count, + + :statistics => { + :total_instances => pool_statistics[:total_instances], + :instances_pending => pool_statistics[:instances_pending], + :instances_failed_count => pool_statistics[:instances_failed_count], + :quota_percent => pool_statistics[:quota_percent], + }, + + :user_can_access_pool_family => user_can_access_pool_family, + :pool_family => { + :name => pool.pool_family.name, + :path => user_can_access_pool_family ? pool_family_path(pool.pool_family) : nil + } + } + end + end diff --git a/src/app/views/pools/_list.html.haml b/src/app/views/pools/_list.html.haml index 5dc5e5d..bd1edd5 100644 --- a/src/app/views/pools/_list.html.haml +++ b/src/app/views/pools/_list.html.haml @@ -24,36 +24,13 @@ });
= filter_table(@header, @pools) do |pool| - - pool_stats = pool.statistics - %tr{:class => cycle('nostripe','stripe')} - %td{:class => 'checkbox'} - %input{:name => "pools_selected[]", :type => "checkbox", :value => pool.id, :id => "pool_checkbox_#{pool.id}" } - %td{:class => 'alert'}= (@statistics[:instances_failed] & pool.instances).present? ? image_tag("sb_icon_instance_failure.png") : "" - %td= link_to(pool.name, pool_path(pool, :view => :filter)) - %td{:class => 'center'}= pool.deployments.count - %td{:class => 'center'}= pool_stats[:total_instances] - %td{:class => 'center'}= pool_stats[:instances_pending] - %td{:class => 'center'}= pool_stats[:instances_failed_count] - %td{:class => 'center'}= pool_stats[:quota_percent] - - if check_privilege(Privilege::VIEW, pool.pool_family) - %td= link_to(pool.pool_family.name, pool.pool_family) - - else - %td= pool.pool_family.name -%script#poolTemplate{ :type => 'text/x-jquery-tmpl' } - :plain - <tr> - <td class="checkbox"><input type="checkbox" id="pool_checkbox_${id}" - name="pools_selected[]" value="${id}"></td> - <td class="alert"> - {{if statistics.instances_failed_count > 0}} - #{image_tag("sb_icon_instance_failure.png")} - {{/if}} - </td> - <td><a href="#{pool_path('replace_id', :view => :filter).sub('replace_id', '${id}')}">${name}</a></td> - <td class="center">${deployments_count}</td> - <td class="center">${statistics.total_instances}</td> - <td class="center">${statistics.instances_pending}</td> - <td class="center">${statistics.instances_failed_count}</td> - <td class="center">${statistics.quota_percent}</td> - <td><a href="#{pool_family_path('replace_id').sub('replace_id', '${pool_family.id}')}">${pool_family.name}</a></td> - </tr> + = render :partial => 'pool_row', :mustache => pool_for_mustache(pool) + +:javascript + $(document).ready(function(){ + $('tr:odd').addClass('stripe'); + $('tr:even').addClass('nostripe'); + }); + +%script#poolRowTemplate{ :type => 'text/html' } + = render :partial => 'pool_row' diff --git a/src/app/views/pools/_pool_row.html.mustache b/src/app/views/pools/_pool_row.html.mustache new file mode 100644 index 0000000..63d3ee2 --- /dev/null +++ b/src/app/views/pools/_pool_row.html.mustache @@ -0,0 +1,26 @@ +<tr> + <td class="checkbox"> + <%= check_box_tag("pools_selected[]", '{{id}}', false, :id => "pool_checkbox_{{id}}") %> + </td> + <td class="alert"> + {{#failed_instances_present}} + <%= image_tag("sb_icon_instance_failure.png") %> + {{/failed_instances_present}} + </td> + <td> + <%= link_to('{{name}}', '{{filter_view_path}}') %> + </td> + <td class="center">{{deployments_count}}</td> + <td class="center">{{statistics.total_instances}}</td> + <td class="center">{{statistics.instances_pending}}</td> + <td class="center">{{statistics.instances_failed_count}}</td> + <td class="center">{{statistics.quota_percent}}</td> + <td> + {{#user_can_access_pool_family}} + <%= link_to('{{pool_family.name}}', '{{pool_family.path}}') %> + {{/user_can_access_pool_family}} + {{^user_can_access_pool_family}} + {{pool_family.name}} + {{/user_can_access_pool_family}} + </td> +</tr> diff --git a/src/public/javascripts/backbone/views.js b/src/public/javascripts/backbone/views.js index 0d29417..4535ac5 100644 --- a/src/public/javascripts/backbone/views.js +++ b/src/public/javascripts/backbone/views.js @@ -31,8 +31,8 @@ Conductor.Views.PoolsIndex = Backbone.View.extend({ template: function() { if (this.currentView() == 'table') { switch(this.currentTab()) { - case 'pools': return $('#poolTemplate'); - case 'deployments': return $('#deploymentTemplate'); + case 'pools': return $('#poolRowTemplate'); + case 'deployments': return $('#deploymentRowTemplate'); case 'instances': return $('#instanceTemplate'); } } @@ -66,7 +66,13 @@ Conductor.Views.PoolsIndex = Backbone.View.extend({ var $table = this.$('table.checkbox_table > tbody'); if($table.length === 0 || $template.length === 0) return; var checkboxes = Conductor.saveCheckboxes('td :checkbox', $table); - $table.empty().append($template.tmpl(this.collection.toJSON())) + + var rowsHtml = ''; + $.each(this.collection.toJSON(), function(index, value) { + rowsHtml += Mustache.to_html($template.html(), value); + }); + + $table.empty().append(rowsHtml); Conductor.restoreCheckboxes(checkboxes, 'td :checkbox', $table); $table.find('tr:even').addClass('nostripe'); $table.find('tr:odd').addClass('stripe');
From: Imre Farkas ifarkas@redhat.com
--- src/app/controllers/pools_controller.rb | 2 +- src/app/helpers/mustache_helper.rb | 6 +++ .../views/instances/_instance_row.html.mustache | 17 ++++++++++ src/app/views/instances/_list.html.haml | 34 +++++-------------- src/public/javascripts/backbone/views.js | 2 +- 5 files changed, 34 insertions(+), 27 deletions(-) create mode 100644 src/app/views/instances/_instance_row.html.mustache
diff --git a/src/app/controllers/pools_controller.rb b/src/app/controllers/pools_controller.rb index 4a3a9d8..ae00567 100644 --- a/src/app/controllers/pools_controller.rb +++ b/src/app/controllers/pools_controller.rb @@ -80,7 +80,7 @@ class PoolsController < ApplicationController when 'pools' render :json => @pools.map{ |pool| view_context.pool_for_mustache(pool) } when 'instances' - render :json => @instances + render :json => @instances.map{ |instance| view_context.instance_for_mustache(instance) } when 'deployments' render :json => @deployments.map{ |deployment| view_context.deployment_for_mustache(deployment) } end diff --git a/src/app/helpers/mustache_helper.rb b/src/app/helpers/mustache_helper.rb index b13ef67..16464f1 100644 --- a/src/app/helpers/mustache_helper.rb +++ b/src/app/helpers/mustache_helper.rb @@ -27,11 +27,17 @@ module MustacheHelper :name => instance.name, :path => instance_path(instance), :uptime => count_uptime(instance.uptime), + :failed => instance.failed?, :translated_state => t("instances.states.#{instance.state}"), :public_addresses => instance.public_addresses.present? ? instance.public_addresses : I18n.t('deployments.pretty_view_show.no_ip_address'), :instance_key_present => instance.instance_key.present?, :stop_enabled => available_actions.include?(InstanceTask::ACTION_STOP), :reboot_enabled => available_actions.include?(InstanceTask::ACTION_REBOOT), + :owner => instance.owner.present? ? instance.owner.name : nil, + + :provider => { + :name => instance.provider_account.present? ? instance.provider_account.provider.name : nil + } } end
diff --git a/src/app/views/instances/_instance_row.html.mustache b/src/app/views/instances/_instance_row.html.mustache new file mode 100644 index 0000000..8d9dd17 --- /dev/null +++ b/src/app/views/instances/_instance_row.html.mustache @@ -0,0 +1,17 @@ +<tr> + <td class="checkbox"> + <%= check_box_tag("instances_selected[]", '{{id}}', false, :id => "instance_checkbox_{{id}}") %> + </td> + <td class="alert"> + {{#failed}} + <%= image_tag("sb_icon_instance_failure.png") %> + {{/failed}} + </td> + <td> + <%= link_to('{{name}}', '{{path}}') %> + </td> + <td>{{public_addresses}}</td> + <td>{{translated_state}}</td> + <td>{{provider.name}}</td> + <td>{{owner}}</td> +</tr> diff --git a/src/app/views/instances/_list.html.haml b/src/app/views/instances/_list.html.haml index dac5d69..b551c43 100644 --- a/src/app/views/instances/_list.html.haml +++ b/src/app/views/instances/_list.html.haml @@ -29,34 +29,18 @@ });
= filter_table(instances_header, @instances) do |instance| - %tr{ :class => cycle('nostripe', 'stripe') } - %td{:class => 'checkbox'} - - selected = params[:select] == 'all' - = check_box_tag "instance_selected[]", instance.id, selected, :id => "instance_checkbox_#{instance.id}" - %td{:class => 'alert'}= instance.failed? ? image_tag("sb_icon_instance_failure.png") : "" - %td= link_to instance.name, instance_path(instance) - %td= instance.public_addresses - %td= t("instances.states.#{instance.state}") - %td= instance.provider_account ? instance.provider_account.provider.name : '' - %td= owner_name(instance) + = render :partial => 'instances/instance_row', :mustache => instance_for_mustache(instance)
:javascript Conductor.setupPrettyFilterURL( '#{url_for(:action => :show, :details_tab => 'instances', :view => 'filter', :page => params[:page])}', '#{url_for(:action => :show, :details_tab => 'instances', :view => 'pretty', :page => params[:page])}');
-%script#instanceTemplate{ :type => 'text/x-jquery-tmpl' } - :plain - <tr> - <td class="checkbox"><input type="checkbox" id="instance_checkbox_${id}" name="instance_selected[]" value="${id}"></td> - <td class="alert"> - {{if is_failed == true}} - #{image_tag("sb_icon_instance_failure.png")} - {{/if}} - </td> - <td><a href="#{instance_path('replace_id').sub('replace_id', '${id}')}">${name}</a></td> - <td>${public_addresses}</td> - <td>${translated_state}</td> - <td>${provider}</td> - <td>${owner}</td> - </tr> +:javascript + $(document).ready(function(){ + $('tr:odd').addClass('stripe'); + $('tr:even').addClass('nostripe'); + }); + +%script#instanceRowTemplate{ :type => 'text/html' } + = render :partial => 'instances/instance_row' diff --git a/src/public/javascripts/backbone/views.js b/src/public/javascripts/backbone/views.js index 4535ac5..055202a 100644 --- a/src/public/javascripts/backbone/views.js +++ b/src/public/javascripts/backbone/views.js @@ -33,7 +33,7 @@ Conductor.Views.PoolsIndex = Backbone.View.extend({ switch(this.currentTab()) { case 'pools': return $('#poolRowTemplate'); case 'deployments': return $('#deploymentRowTemplate'); - case 'instances': return $('#instanceTemplate'); + case 'instances': return $('#instanceRowTemplate'); } } else if (this.currentView() == 'pretty') {
Dne 18.4.2012 14:41, ifarkas@redhat.com napsal(a):
This is a fixed and rebased version of the previous revision.
It also uses an updated version of the mustache gem which supports accessing nested attributes using the dot notation. The updated gem is temporarily accessible only from the testing repo: https://admin.fedoraproject.org/updates/rubygem-mustache-0.99.4-4.fc15 https://admin.fedoraproject.org/updates/rubygem-mustache-0.99.4-4.fc16 https://admin.fedoraproject.org/updates/rubygem-mustache-0.99.4-4.fc17 https://admin.fedoraproject.org/updates/rubygem-mustache-0.99.4-4.el6
Testing and kamra of rubygem-mustache is appreciated ;) Imre, thank you for testing.
Vit
On 04/18/2012 02:58 PM, Vít Ondruch wrote:
Dne 18.4.2012 14:41, ifarkas@redhat.com napsal(a):
This is a fixed and rebased version of the previous revision.
It also uses an updated version of the mustache gem which supports accessing nested attributes using the dot notation. The updated gem is temporarily accessible only from the testing repo: https://admin.fedoraproject.org/updates/rubygem-mustache-0.99.4-4.fc15 https://admin.fedoraproject.org/updates/rubygem-mustache-0.99.4-4.fc16 https://admin.fedoraproject.org/updates/rubygem-mustache-0.99.4-4.fc17 https://admin.fedoraproject.org/updates/rubygem-mustache-0.99.4-4.el6
Testing and kamra of rubygem-mustache is appreciated ;) Imre, thank you for testing.
Vit
Thanks *you* for the packaging! Imre
aeolus-devel@lists.fedorahosted.org