Screencast: Mercury Online Editor

Mercury ist ein auf HTML5 basierender Web-Editor mit dem Inhalte direkt im Browser bearbeitet werden können. In dem folgenden Screencast zeigt Ryan wie es in eigenen Applikationen eingebunden und benutzt werden kann.

 

Downloads in verschiedenen Formaten:

mp4
m4v
webm
ogg

 

Resourcen:

Gemfile

[ruby]
gem ‚mercury-rails‘, git: ‚https://github.com/jejacks0n/mercury.git‘, ref: ‚a2b16bcdc9‘
[/ruby]

bash

[bash]
bundle
rails g mercury:install
rake mercury_engine:install:migrations
rake db:migrate
[/bash]

pages/show.html.erb

[html]
<h1><span id="page_name" class="mercury-region" data-type="editable"><%= raw @page.name %></span></h1>

<div id="page_content" class="mercury-region" data-type="editable">
<%= raw @page.content %>
</div>
<p><%= link_to "Edit Page", "/editor" + request.path, id: "edit_link", data: {save_url: mercury_update_page_path(@page)} %></p>
[/html]

config/routes.rb

[ruby]
resources :pages do
member { post :mercury_update }
end
[/ruby]

pages_controller.rb

[ruby]
def mercury_update
page = Page.find(params[:id])
page.name = params[:content][:page_name][:value]
page.content = params[:content][:page_content][:value]
page.save!
render text: ""
end
[/ruby]

app/assets/javascripts/mercury.js

[javascript]
$(window).bind(‚mercury:ready‘, function() {
var link = $(‚#mercury_iframe‘).contents().find(‚#edit_link‘);
Mercury.saveURL = link.data(’save-url‘);
link.hide();
});

$(window).bind(‚mercury:saved‘, function() {
window.location = window.location.href.replace(//editor//i, ‚/‘);
});
[/javascript]

views/layouts/mercury.html.erb

[html]

saveStyle: ‚form‘,

[/html]

Screencast: Markdown mit Redcarpet

Markdown ist eine vereinfachte Möglichkeit beliebige Texte in HTML umzuwandeln. Dabei wird eine Syntax benutzt die es erlaubt verschiedene HTML Elemente durch Verwendung von Schlüsselwörter und Einrückungen zu erzeugen. Ryan zeigt diese Woche wie Redcarpet dafür eingesetzt werden kann und zusätzlich wie Syntaxhighlighting für Quellcode-Texte eingebunden wird.

 

Downloads in verschiedenen Formaten:

source code
mp4
m4v
webm
ogv

 

Resourcen:

bash

[bash]
sudo easy_install pygments
[/bash]

Gemfile

[ruby]
gem ‚redcarpet‘
gem ‚albino‘
gem ’nokogiri‘
[/ruby]

application_helper.rb

[ruby]
def markdown(text)
options = [:hard_wrap, :filter_html, :autolink, :no_intraemphasis, :fenced_code, :gh_blockcode]
syntax_highlighter(Redcarpet.new(text, *options).to_html).html_safe
end

def syntax_highlighter(html)
doc = Nokogiri::HTML(html)
doc.search("//pre[@lang]").each do |pre|
pre.replace Albino.colorize(pre.text.rstrip, pre[:lang])
end
doc.to_s
end
[/ruby]

articles/show.html.erb

[html]
<%= markdown(@article.content) %>
[/html]

Screencast: Vererbung von Templates

Teile von Templates wieder zu verwenden wurde bisher größtenteils über partials verwirklicht. In Rails 3.1 wird es möglich sein Templates zu vererben. So können Teile von Views auf allgemein gültige zurückgreifen und darstellen. Ryan zeigt diese Woche wie in einer Applikation ein Template von allen Views genutzt und wie es im Zusamenhang mit Subdomains eingesetzt werden kann.

 

Downloads in verschiedenen Formaten:

source code
mp4
m4v
webm
ogv

 

Resourcen:

application_controller.rb

[ruby]
before_filter :subdomain_view_path

private

def subdomain_view_path
prepend_view_path "app/views/#{request.subdomain}_subdomain" if request.subdomain.present?
end
[/ruby]

views/layouts/application.html.erb

[html]
<%= render "side" %>
[/html]

views/application/_side.html.erb

[html]
<strong>Pages</strong>
<ul>
<li><%= link_to "Home", root_path %></li>
<li><%= link_to "Products", products_path %></li>
</ul>
[/html]

views/admin/base/_side.html.erb

[html]
<strong>Pages</strong>
<ul>
<li><%= link_to "Home", root_path %></li>
<li><%= link_to "Products", products_path %></li>
<li><%= link_to "Manage Products", admin_products_path %></li>
<li><%= link_to "Manage Categories", admin_categories_path %></li>
</ul>
[/html]

views/mobile_subdomain/products/index.html.erb

[html]
<h1>Mobile Version</h1>
[/html]

edit.html.erb

[html]
<%= controller.view_paths %>
[/html]

Screencast: Sortierbare Tabellen

Ryan zeigt in diesem Screencast wie Tabellen auf- und absteigend sortiert werden können.

 

Download:

Download(16.2 MB, 10:52)
Alternativer Download für iPod & Apple TV(15.4 MB, 10:52)

 

Resourcen:

 

Quellcode:

[ruby]
class ProductsController < ApplicationController
helper_method :sort_column, :sort_direction

def index
@products = Product.order(sort_column + " " + sort_direction)
end

# …

private

def sort_column
Product.column_names.include?(params[:sort]) ? params[:sort] : "name"
end

def sort_direction
%w[asc desc].include?(params[:direction]) ? params[:direction] : "asc"
end
end

# application_helper.rb
def sortable(column, title = nil)
title ||= column.titleize
css_class = column == sort_column ? "current #{sort_direction}" : nil
direction = column == sort_column && sort_direction == "asc" ? "desc" : "asc"
link_to title, {:sort => column, :direction => direction}, {:class => css_class}
end
[/ruby]

[html]
<!– products/index.html.erb –>
<tr>
<th><%= sortable "name" %></th>
<th><%= sortable "price" %></th>
<th><%= sortable "released_at", "Released" %></th>
</tr>
[/html]

[css]
/* application.css */
.pretty th .current {
padding-right: 12px;
background-repeat: no-repeat;
background-position: right center;
}

.pretty th .asc {
background-image: url(/images/up_arrow.gif);
}

.pretty th .desc {
background-image: url(/images/down_arrow.gif);
}
[/css]

Screencast: Diagramme in Rails Applikationen verwenden

Bilder sagen mehr tausend Worte und daher werden oft Diagramme zur Visualisierung von Daten eingesetzt. Ryan zeigt diese Woche wie Highchart für Diagramme und Grafen innerhalb einer Railsapplikation eingesetzt werden kann.

 

Download:

Download(29.1 MB, 16:12)
Alternativer Download für iPod & Apple TV(27.4 MB, 16:12)

 

Resourcen:

 

Quellcode:

[html]
<!– layouts/application.html.erb –>
<%= javascript_include_tag "jquery-1.4.2.min", "rails", "highcharts" %>

<!– orders/index.html.erb –>
<script type="text/javascript" charset="utf-8">
$(function() {
new Highcharts.Chart({
chart: {
renderTo: "orders_chart"
},
title: {
text: "Orders by Day"
},
xAxis: {
type: "datetime"
},
yAxis: {
title: {
text: "Dollars"
}
},
tooltip: {
formatter: function() {
return Highcharts.dateFormat("%B %e, %Y", this.x) + ‚: ‚ +
"$" + Highcharts.numberFormat(this.y, 2);
}
},
series: [
<% { "Download" => Order.download, "Shipping" => Order.shipping }.each do |name, orders| %>
{
name: "<%= name %>",
pointInterval: <%= 1.day * 1000 %>,
pointStart: <%= 3.weeks.ago.to_i * 1000 %>,
data: <%= orders_chart_series(orders, 3.weeks.ago) %>
},
<% end %>
]
});
});
</script>
<div id="orders_chart" style="width:560px; height:300px;"></div>
[/html]

[ruby]
# rails c
Order.group("date(purchased_at)").select("purchased_at, sum(total_price) as total_price").first.total_price.to_f
Order.group("date(purchased_at)").select("purchased_at, sum(total_price) as total_price").first.purchased_at.to_date

# models/order.rb
scope :shipping, where(:shipping => true)
scope :download, where(:shipping => false)

def self.total_on(date)
where("date(purchased_at) = ?", date).sum(:total_price)
end

# orders_helper.rb
def orders_chart_series(orders, start_time)
orders_by_day = orders.where(:purchased_at => start_time.beginning_of_day..Time.zone.now.end_of_day).
group("date(purchased_at)").
select("purchased_at, sum(total_price) as total_price")
(start_time.to_date..Date.today).map do |date|
order = orders_by_day.detect { |order| order.purchased_at.to_date == date }
order && order.total_price.to_f || 0
end.inspect
end
[/ruby]

Screencast: PDF Dokumente mit PDFKit generieren

PDFs mit Ruby zu erzeugen ist, trotz PDF Toolkit und Prawn, eine langwierige Angelegenheit bzw. kann aufwendig werden. Mit PDFKit können die Dokumente aus HTML-Dateien generiert werden.

 

Download:

Download(18.5 MB, 8:14)
Alternativer Download für iPod & Apple TV(16.8 MB, 8:14)

 

Resourcen:

 

Quellcode:

[bash]
bundle install
rake middleware
[/bash]

[ruby]
# config/application.rb
config.middleware.use "PDFKit::Middleware", :print_media_type => true
[/ruby]

[html]
<!– layouts/application.html.erb –>
<%= stylesheet_link_tag ‚application‘, :media => "all" %>

<!– orders/show.html.erb –>
<p id="pdf_link"><%= link_to "Download Invoice (PDF)", order_path(@order, :format => "pdf") %></p>
[/html]

[css]
/* application.css */
@media print {
body {
background-color: #FFF;
}

#container {
width: auto;
margin: 0;
padding: 0;
border: none;
}

#line_items {
page-break-before: always;
}

#pdf_link {
display: none;
}
}
[/css]

Screencast: Mehrstufige Formulare

Je nach nach Umfang und Komplexität ist es notwendig ein Formular in mehrere Schritte aufzuteilen. Diese Woche zeigt Ryan in seinem Screencast, wie dies mit Rails gelöst werden kann.

 

Download:

Download(21.8 MB, 15:14)
Alternativer Downloadfür iPod & Apple TV(20.9 MB, 15:14)

 

Resourcen:

 

Quellcode:

[bash]
script/generate nifty_scaffold order shipping_name:string billing_name:string index show new
[/bash]

[ruby]
# models/order.rb
attr_writer :current_step

validates_presence_of :shipping_name, :if => lambda { |o| o.current_step == "shipping" }
validates_presence_of :billing_name, :if => lambda { |o| o.current_step == "billing" }

def current_step
@current_step || steps.first
end

def steps
%w[shipping billing confirmation]
end

def next_step
self.current_step = steps[steps.index(current_step)+1]
end

def previous_step
self.current_step = steps[steps.index(current_step)-1]
end

def first_step?
current_step == steps.first
end

def last_step?
current_step == steps.last
end

def all_valid?
steps.all? do |step|
self.current_step = step
valid?
end
end

# orders_controller.rb
def new
session[:order_params] ||= {}
@order = Order.new(session[:order_params])
@order.current_step = session[:order_step]
end

def create
session[:order_params].deep_merge!(params[:order]) if params[:order]
@order = Order.new(session[:order_params])
@order.current_step = session[:order_step]
if @order.valid?
if params[:back_button]
@order.previous_step
elsif @order.last_step?
@order.save if @order.all_valid?
else
@order.next_step
end
session[:order_step] = @order.current_step
end
if @order.new_record?
render "new"
else
session[:order_step] = session[:order_params] = nil
flash[:notice] = "Order saved!"
redirect_to @order
end
end
[/ruby]

[html]
<!– orders/new.html.erb –>
<% form_for @order do |f| %>
<%= f.error_messages %>
<%= render "#{@order.current_step}_step", :f => f %>
<p><%= f.submit "Continue" %></p>
<p><%= f.submit "Back", :name => "back_button" unless @order.first_step? %></p>
<% end %>
[/html]

Screencast: A/B Tests mit A/Bingo

A/B Tests oder Split-Tests werden verwendet um die Akzeptanz einer Applikation in zwei verschiedenen Ausprägungen zu prüfen. In dem heutigen Screencast wird dazu A/Bingo vorgestellt und vorgeführt wie es dazu verwendet werden kann.

 

Download:

Download(35.1 MB, 11:04)
Alternativer Downloadfür iPod & Apple TV(27.6 MB, 11:04)

 

Resourcen:

 

Quellcode:

[bash]
script/plugin install git://git.bingocardcreator.com/abingo.git
script/generate abingo_migration
rake db:migrate
script/generate controller abingo_dashboard
script/plugin install –force git://github.com/ryanb/abingo.git
[/bash]

[ruby]
# users_controller.rb
bingo! "signup_intro"
bingo! "signup_title"
# or
bingo! "signup"

# application_controller.rb
before_filter :set_abingo_identity

private

def set_abingo_identity
if request.user_agent =~ /b(Baidu|Gigabot|Googlebot|libwww-perl|lwp-trivial|msnbot|SiteUptime|Slurp|WordPress|ZIBB|ZyBorg)b/i
Abingo.identity = "robot"
elsif current_user
Abingo.identity = current_user.id
else
session[:abingo_identity] ||= rand(10 ** 10)
Abingo.identity = session[:abingo_identity]
end
end

# abingo_dashboard_controller.rb
class AbingoDashboardController < ApplicationController
# TODO add some authorization
include Abingo::Controller::Dashboard
end

# routes.rb
map.abingo_dashboard "/abingo/:action/:id", :controller=> :abingo_dashboard
[/ruby]

[html]
<% ab_test("signup_title", ["Sign up", "Registration", "Free Sign up"], :conversion => "signup") do |signup_title| %>
<% title "Free Sign up" %>
<% end %>

<% if ab_test "signup_intro", nil, :conversion => "signup" %>
<p>…</p>
<% end %>
[/html]

Screencast: Kalender-Funktion

Es gibt verschiedene Möglichkeiten um einem Benutzer ein Datum auswählen zu lassen oder einen Kalender zu präsentieren. In dieser Woche zeigt Ryan einige Beispiele und Lösungen dafür.

 

Download:

Download(15.6 MB, 9:50)
Alternativer Downloadfür iPod & Apple TV(14.9 MB, 9:50)

 

Resourcen:

 

Quellcode:

[bash]
script/plugin install git://github.com/p8/table_builder.git
[/bash]

[ruby]
# articles_controller.rb
def index
@articles = Article.find(:all)
@date = params[:month] ? Date.parse(params[:month]) : Date.today
endv
[/ruby]

[html]
<!– layouts/application.html.erb –>
<%= stylesheet_link_tag "http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/redmond/jquery-ui.css", "application" %>
<%= javascript_include_tag "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js", "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.1/jquery-ui.min.js", "application" %>

<!– articles/index.html.erb –>
<div id="calendar">
<h2 id="month">
<%= link_to "<", :month => (@date.beginning_of_month-1).strftime("%Y-%m") %>
<%=h @date.strftime("%B %Y") %>
<%= link_to ">", :month => (@date.end_of_month+1).strftime("%Y-%m") %>
</h2>
<% calendar_for @articles, :year => @date.year, :month => @date.month do |calendar| %>
<%= calendar.head(‚Sunday‘, ‚Monday‘, ‚Tuesday‘, ‚Wednesday‘, ‚Thursday‘, ‚Friday‘, ‚Saturday‘) %>
<% calendar.day(:day_method => :published_on) do |date, articles| %>
<%= date.day %>
<ul>
<% for article in articles %>
<li><%= link_to h(article.name), article %></li>
<% end %>
</ul>
<% end %>
<% end %>
</div>

<!– articles/_form.html.erb –>
<%= f.text_field :published_on %>
[/html]

[javascript]
// application.js
$(function() {
$("#article_published_on").datepicker();
});
[/javascript]

[css]
#calendar table {
border-collapse: collapse;
width: 100%;
}

#calendar td,
#calendar th {
font-family: "Lucida Grande",arial,helvetica,sans-serif;
font-size: 10px;
padding: 6px;
border: 1px solid #999;
}

#calendar th {
background: #DDD;
color: #666;
text-align: center;
width: 14.2857142857143%;
}

#calendar td {
background: #FFF;
color: #777;
height: 80px;
vertical-align: top;
font-size: 16px;
}

#calendar .notmonth {
color: #CCC;
}

#calendar #month {
margin: 0;
padding-top: 10px;
padding-bottom: 10px;
text-align: center;
}

#calendar #month a, #calendar #month a:hover {
text-decoration: none;
padding: 0 10px;
color: #999;
}

#calendar .today {
background-color: #D7F2FF;
}

#calendar ul {
margin: 0;
margin-top: 5px;
padding: 0;
list-style: none;
}

#calendar li {
margin: 0;
padding: 0;
font-size: 11px;
text-align: center;
}
[/css]

Screencast: ERB Blöcke in Rails 3

In Rails 3 Beta 2 hat sich die Verwendung von Blöcken in ERB Templates geändert. Ryan zeigt in dieser Woche wie sie benutzt werden können.

 

Download:

Download (21.2 MB, 9:41)
Alternativer Download für iPod & Apple TV (18 MB, 9:41)

 

Resourcen:

 

Quellcode:

[bash]
rvm install ruby-head
rvm ruby-head
gem install rails –pre
bundle install
[/bash]

[ruby]
# Gemfile
gem "rails", "3.0.0.beta2"

# application_helper.rb
def admin_area(&block)
content = with_output_buffer(&block)
content_tag(:div, content, :class => "admin")
end
# or
def admin_area(&block)
content_tag(:div, :class => "admin", &block) if admin?
end
[/ruby]

[html]
<%= form_for @product do |f| %>
<% end %>

<%= div_for @product do %>
<% end %>

<% @comments.each do |c| %>
<% end %>

<% content_for :side do %>
<% end %>

<% cache do %>
<% end %>

<!– products/show.html.erb –>
<%= admin_area do %>
<%= link_to "Edit", edit_product_path(@product) %> |
<%= link_to "Destroy", @product, :confirm => "Are you sure?", :method => :delete %> |
<%= link_to "View All", products_path %>
<% end %>
[/html]