Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
百⼤大媒體網站
從 wordpress 到 rails 的
⼤大⼩小事
Ronald Hsu (hothero)
Technical Director, backer-founder.com
http://blog.hothero.org
@h...
What’s the talk about?
• No diabolic tricks and wicked craft
• A year experience sharing
• Goes through our practice
• You...
What’s the talk about?
• No diabolic tricks and wicked craft
• A year experience sharing
• Goes through our practice
• You...
Backer-Founder
• First and leading crowdfunding consulting
agency in Taiwan
• Has carried out 40 projects to domestic and
...
Backer-Founder
Backer-Founder
Backer-Founder
http://xkcd.com/323/
Backer-Founder
TNL
• A group of people who are dissatisfied with the
existing media environment and want to make a
difference.
• We aspire...
X
X
Our Progress & Goal
Backend

+

DB Schema
Frontend
Wordpress
• WordPress is a free and open-source content
management system (CMS) based on PHP and
MySQL.
• Features include...
Wordpress
Wordpress
Wordpress
Wordpress
Wordpress
Wordpress
• More than 30000 commits
• 23+ contributors
• 127+ version releases
• Nearly 500,000 lines of code, which conta...
But why?
Three Main Issues
Customization

Difficulty
Few Wordpress 

Developer in T.W.
Performance
Issue
Three Main Issues
Customization

Difficulty
Few Wordpress 

Developer in T.W.
Performance
Issue
Three Main Issues
Customization

Difficulty
Few Wordpress 

Developer in T.W.
Performance
Issue
Three Main Issues
Customization

Difficulty
Few Wordpress 

Developer in T.W.
Performance
Issue
Three Main Issues
Customization

Difficulty
Few Wordpress 

Developer in T.W.
Performance
Issue
So...we start to use rails
Our Progress & Goal
Backend

+

DB Schema
Frontend
Wordpress
DB Schema
• posts, pages, custom
post types,
attachments, links,
navigation menu items,
categories, tags,
custom...
Wordpress Structure
posts
pages
custom post types
post metadata
options
categories
users
attachments
taxonomy terms
tags
n...
Wordpress Structure
posts
pages
custom post types
post metadata
options
categories
users
attachments
taxonomy terms
tags
n...
General in Post Editing
has_many
has_many
It means static
content
Post
Attachment
Revision
Page
posts
pages
custom post
attachments
navigation menu
wp_posts
But in wordpress …
wp_posts
revisions
attachments
nav menu it...
But in wordpress …
• All of those we mentioned before are in
only one table.
• Also include custom post types, links,
navi...
In Rails
1 has_many :attachments, -> { where(post_type:
2 "attachment") },
3 foreign_key:
4 "post_parent",
5 class_name:
6...
posts
pages
custom post
types
attachments
navigation menu
items
wp_posts
Tag / Category
categories
taxonomy terms
tags
wp_...
Wordpress DB Schema
In practice
• Category
• wp_term_taxonomy.taxonomy: category
• wp_terms.name: Politics
• Tag
• wp_term_taxonomy.taxonomy: ...
In Rails1 # models/w_post.rb
2 has_many :w_terms, through: :
3 w_term_relationships, foreign_key: "term_id"
4 has_many :w_...
In Rails1 # models/w_post.rb
2 has_many :w_terms, through: :
3 w_term_relationships, foreign_key: "term_id"
4 has_many :w_...
If you need to know more…
• http://codex.wordpress.org/Database_Description
• http://code.tutsplus.com/tutorials/understan...
And we made a gem
• wpdb_activerecord: https://github.com/hothero/
wpdb_activerecord
• It’s a ORM wrapper for the WordPres...
wpdb_activerecord
1 # Gemfile
2 gem "wpdb_activerecord"
3
4 # Post
5 WPDB::Post.all # Get all posts
6 @post = WPDB::Post.f...
wpdb_activerecord -
advanced
1 # config/wpdb_activerecord.yml
2 WPDB_PREFIX: "cgjbugpbs_"
# the table of WPDB::Post is cgj...
wpdb - installation
wpdb - installation
wpdb - installation
wpdb - installation
wpdb - installation
wpdb -usage
wpdb -usage
wpdb -usage
wpdb -usage
wpdb -usage
wpdb -usage
wpdb -usage
wpdb -usage
Our Progress & Goal
Backend

+

DB Schema
Frontend
wpdb_activerecord
Server Side
Visitors
i0.wp.com/…
Cloudflare - Page Rules
And we done
pcu 6000 ⬆ NT$5000 ⬇
Monthly Data
• 7 million pageview ⬆
• 1.2 hundred million
requests ⬆
• 4 million UU ⬆
2015/02
Our Progress & Goal
Backend

+

DB Schema
Frontend
CMS Admin
Edit Flow
Media Gallery
Globalize
Cronjob
editflow.org
• Edit Flow gives you custom statuses, a calendar, editorial comments, and
more, all to make it much easier fo...
Editor Structure
Author
Senior

Editor
Chief

Editor
ready to 

review
ready to 

check
publish
Normal Flow
Editor
Edit Flow
Calendar
Custom Statuses
Notifications
Editorial Comments
• Threaded commenting in the admin for private
discussion between writers and editors.
Editorial Comments
• Use this gem: acts_as_commentable
• Polymorphic Associations
1 commentable = Post.create
2 comment = ...
What’s the Polymorphic
Associations
• Assume a situation
• An employee has many pictures
• A Product has many pictures
• A...
What’s the Polymorphic
Associations
• In general: two relationship tables to associate objects
and pictures
Employee
Produ...
What’s the Polymorphic
Associations
• Level up: an additional table to associate
Employee
Product
Object

Relationship
obj...
What’s the Polymorphic
Associations
• Polymorphic Associations
Employee
Product
Picture
imageable_id
imageable_type
will b...
What’s the Polymorphic
Associations
• Practice in Rails.
What’s the Polymorphic
Associations
• In migration
editflow.org
• Edit Flow gives you custom statuses, a calendar, editorial comments, and
more, all to make it much easier fo...
Story Budget
• View all of your upcoming posts in a more traditional story
budget view, and hit the print button to take i...
Search Design In General
• In general, we maybe use many conditions to match different
situation. 1 def search
2 @posts = ...
Search Design In General
• In general, we maybe use many conditions to match different
situation. 1 def search
2 @posts = ...
Ransack - View Helper1 <%= search_form_for @q do |f| %>
2 # Search if the name field contains...
3 <%= f.label :name_cont ...
Ransack - View Helper1 <%= search_form_for @q do |f| %>
2 # Search if the name field contains...
3 <%= f.label :name_cont ...
Ransack - View Helper1 <%= search_form_for @q do |f| %>
2 # Search if the name field contains...
3 <%= f.label :name_cont ...
Ransack - Controller
1 def index
2 @q = Person.ransack(params[:q])
3 @people = @q.result(distinct: true)
4 end
Ransack - Controller
1 def index
2 @q = Person.ransack(params[:q])
3 @people = @q.result(distinct: true)
4 end
In Practice
q[status_scope]
q[author_id_eq]
q[post_type_eq]
q[author_name_cont]
q[updated_at_gteq] - q[updated_at_lteq]
editflow.org
• Edit Flow gives you custom statuses, a calendar, editorial comments, and
more, all to make it much easier fo...
User Groups
• Keep your users organized by department or function.
Editor Structure
Author
Senior

Editor
Chief

Editor
Editor
Maybe DB Schema
User Author Editor Admin
or
User
user_type
STI (Single-table inheritance)
class User < ActiveRecord::Base
end
class Author < User
enum role: [:normal, :blogger]
def ...
STI with Priority Problem
• STI is unfit for priority feature.
• Chief Editor > Senior Editor > Editor > Author
• Enum-desi...
Other parts
• Except edit-flow, there are some more features
• takeover & editing lock
• media gallery
• globalize
A situation
Author
Editor
wanna edit
takeover & editing lock
• Use this gem: message_bus
• MessageBus implements a Server to Server
channel protocol and Server...
• We use current_editor_id field as lock in post.
• Subscribe a channel for takeover when start editing in front-
end.
• Pu...
Media Gallery
Media Gallery - Tricks
Browsers don't allow file
uploads via XMLHttpRequest
(aka XHR) for security reasons.
General in jQuery
• Hijack the forms submit event to execute our custom
iFrame-method function
• Submit the form to the iF...
remotipart
• Use this gem: remotipart
• Remotipart is a Ruby on Rails gem enabling AJAX file
uploads with jQuery in Rails 3...
Globalize
globalize
• Use this gem: globalize
• Each locale have their owned tags & revisions
1 # config/initializers/post_translati...
Mobile APP
• http://apps.thenewslens.com/
API Design In General
class ApiController < ApplicationController
def all
# get review & news type post
case params[:post_...
has_scope
• Use this gem: has_scope
• In model
1 class Graduation < ActiveRecord::Base
2 scope :featured, -> { where(:feat...
has_scope
• You can use those named scopes as filters by declaring
them on your controller and just need to call apply_scop...
has_scope
• You can use those named scopes as filters by declaring
them on your controller and just need to call apply_scop...
has_scope
• You can use those named scopes as filters by declaring
them on your controller and just need to call apply_scop...
has_scope
• You can use those named scopes as filters by declaring
them on your controller and just need to call apply_scop...
Tragedy at the admin theme
Find out a good design
which have smooth
operating and fancy
turbolinks & pjax
• Instead of letting the browser recompile the JavaScript and
CSS between each page change, it keeps the...
rails-gem-list
• A workman must sharpen his tools if he is to do his work
well / ⼯工欲善其事,必先利其器
• We’ve done a gem: rails-ge...
rails-gem-list
• A workman must sharpen his tools if he is to do his work
well / ⼯工欲善其事,必先利其器
• We’ve done a gem: rails-ge...
Finally
• If you want to do a media website, you can follow edit-flow to
manage your posts.
• If your WordPress website bec...
Special Thanks
X
@dlackty @ymowov
@baojjeu @st0012 @nanasyu @eugg @chentyphoon @randyhsieh @fufukwang
Contact me: hothero@...
2015 rubyconf - 百大媒體網站從 Wordpress 到 Rails 的大小事
Upcoming SlideShare
Loading in …5
×

2015 rubyconf - 百大媒體網站從 Wordpress 到 Rails 的大小事

6,891 views

Published on

WordPress 簡易的架設與強大的後台讓人愛不釋手,但其令人垢病的低落效能讓一個台灣百大的媒體網站,每每遇到重要時事新聞常因突然過大的龐大流量導致無法負荷。這次將分享將近一年時間,從 WordPress 前台+Rails 後台,一步步到全站 Rails 過程的大小事,包含資料庫、程式與伺服器架構設計等。

其中我們也 release 了兩個 Gem:
* wpdb_activerecord: https://github.com/hothero/wpdb_activerecord
* rails-gem-list: https://github.com/hothero/rails-gem-list

Published in: Technology
  • DOWNLOAD FULL BOOKS, INTO AVAILABLE FORMAT ......................................................................................................................... ......................................................................................................................... ,DOWNLOAD FULL. PDF EBOOK here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ,DOWNLOAD FULL. EPUB Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ,DOWNLOAD FULL. doc Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ,DOWNLOAD FULL. PDF EBOOK here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ,DOWNLOAD FULL. EPUB Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ,DOWNLOAD FULL. doc Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ......................................................................................................................... ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • ♣♣ 10 Easy Ways to Improve Your Performance in Bed...  https://tinyurl.com/rockhardxxx
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • ➤➤ 3 Reasons Why You Shouldn't take Pills for ED (important) ■■■ https://tinyurl.com/rockhardxx➤➤ How Long Does She Want You to Last? Here's the link to the FREE report ▲▲▲ http://ishbv.com/rockhardx/pdf
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • ➤➤ 3 Reasons Why You Shouldn't take Pills for ED (important)  https://tinyurl.com/rockhardxxx
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

2015 rubyconf - 百大媒體網站從 Wordpress 到 Rails 的大小事

  1. 1. 百⼤大媒體網站 從 wordpress 到 rails 的 ⼤大⼩小事 Ronald Hsu (hothero) Technical Director, backer-founder.com http://blog.hothero.org @hothero slide: http://backme.tw/ref/wp-rails
  2. 2. What’s the talk about? • No diabolic tricks and wicked craft • A year experience sharing • Goes through our practice • You will know more gems • You will know what media websites care about most • You will know how to handle larger traffic for media websites • Nothing funny
  3. 3. What’s the talk about? • No diabolic tricks and wicked craft • A year experience sharing • Goes through our practice • You will know more gems • You will know what media websites care about most • You will know how to handle larger traffic for media websites • Nothing funny
  4. 4. Backer-Founder • First and leading crowdfunding consulting agency in Taiwan • Has carried out 40 projects to domestic and abroad • Raised over $7 million in 11 months since its establishment in October 2014.
  5. 5. Backer-Founder
  6. 6. Backer-Founder
  7. 7. Backer-Founder http://xkcd.com/323/
  8. 8. Backer-Founder
  9. 9. TNL • A group of people who are dissatisfied with the existing media environment and want to make a difference. • We aspire to build a media that provides not only facts, but also diverse perspectives.
  10. 10. X
  11. 11. X
  12. 12. Our Progress & Goal Backend
 +
 DB Schema Frontend
  13. 13. Wordpress • WordPress is a free and open-source content management system (CMS) based on PHP and MySQL. • Features include a plugin architecture and a template system. • WordPress was used by more than 23.3% of the top 10 million websites as of January 2015. • Initial release May 27, 2003 (12 years ago) http://www.wikiwand.com/en/WordPress
  14. 14. Wordpress
  15. 15. Wordpress
  16. 16. Wordpress
  17. 17. Wordpress
  18. 18. Wordpress
  19. 19. Wordpress • More than 30000 commits • 23+ contributors • 127+ version releases • Nearly 500,000 lines of code, which contains nearly 300,000 lines of php code https://github.com/wordpress/wordpress
  20. 20. But why?
  21. 21. Three Main Issues Customization
 Difficulty Few Wordpress 
 Developer in T.W. Performance Issue
  22. 22. Three Main Issues Customization
 Difficulty Few Wordpress 
 Developer in T.W. Performance Issue
  23. 23. Three Main Issues Customization
 Difficulty Few Wordpress 
 Developer in T.W. Performance Issue
  24. 24. Three Main Issues Customization
 Difficulty Few Wordpress 
 Developer in T.W. Performance Issue
  25. 25. Three Main Issues Customization
 Difficulty Few Wordpress 
 Developer in T.W. Performance Issue
  26. 26. So...we start to use rails
  27. 27. Our Progress & Goal Backend
 +
 DB Schema Frontend
  28. 28. Wordpress DB Schema • posts, pages, custom post types, attachments, links, navigation menu items, categories, tags, custom taxonomies, taxonomy terms, post metadata, widgets, options, users, hardcoded content, third party content http://goo.gl/Tbbpfr
  29. 29. Wordpress Structure posts pages custom post types post metadata options categories users attachments taxonomy terms tags navigation menu items widgets custom taxonomieswp_posts wp_terms wp_term_ taxonomy wp_post_ meta wp_optio ns wp_users wp_links links
  30. 30. Wordpress Structure posts pages custom post types post metadata options categories users attachments taxonomy terms tags navigation menu items widgets custom taxonomieswp_posts wp_terms wp_term_ taxonomy wp_post_ meta wp_optio ns wp_users wp_links links Post
 Editing Tag/
 Category
  31. 31. General in Post Editing has_many has_many It means static content Post Attachment Revision Page
  32. 32. posts pages custom post attachments navigation menu wp_posts But in wordpress … wp_posts revisions attachments nav menu items
  33. 33. But in wordpress … • All of those we mentioned before are in only one table. • Also include custom post types, links, navigation menu items!!! post_type •post •page •revision •attachment •nav_menu_item •…
  34. 34. In Rails 1 has_many :attachments, -> { where(post_type: 2 "attachment") }, 3 foreign_key: 4 "post_parent", 5 class_name: 6 "Post" 7 has_many :revisions, -> { where(post_type: 8 "revision") }, 9 foreign_key: 10 "post_parent", 11 class_name: "Post"
  35. 35. posts pages custom post types attachments navigation menu items wp_posts Tag / Category categories taxonomy terms tags wp_terms
  36. 36. Wordpress DB Schema
  37. 37. In practice • Category • wp_term_taxonomy.taxonomy: category • wp_terms.name: Politics • Tag • wp_term_taxonomy.taxonomy: post_tag • wp_terms.name: FireChat
  38. 38. In Rails1 # models/w_post.rb 2 has_many :w_terms, through: : 3 w_term_relationships, foreign_key: "term_id" 4 has_many :w_term_relationships, foreign_key: 5 "object_id" 6 has_many :tags, 7 -> { where("#{WTermTaxonomy.table_name}.taxonomy = 'post_tag'") }, 9 through: :w_terms, source: :w_term_taxonomy, 10 class_name: "WTerm" 11 has_many :categories, 12 -> { where("#{WTermTaxonomy.table_name}.taxonomy = 'category'") }, 14 through: :w_terms, source: :w_term_taxonomy, 15 class_name: "WTerm" 16 17 # models/w_term_relationship.rb 18 belongs_to :w_term_taxonomy, foreign_key: 19 "term_taxonomy_id" 20 has_one :w_term, :through => :w_term_taxonomy
  39. 39. In Rails1 # models/w_post.rb 2 has_many :w_terms, through: : 3 w_term_relationships, foreign_key: "term_id" 4 has_many :w_term_relationships, foreign_key: 5 "object_id" 6 has_many :tags, 7 -> { where("#{WTermTaxonomy.table_name}.taxonomy = 'post_tag'") }, 9 through: :w_terms, source: :w_term_taxonomy, 10 class_name: "WTerm" 11 has_many :categories, 12 -> { where("#{WTermTaxonomy.table_name}.taxonomy = 'category'") }, 14 through: :w_terms, source: :w_term_taxonomy, 15 class_name: "WTerm" 16 17 # models/w_term_relationship.rb 18 belongs_to :w_term_taxonomy, foreign_key: 19 "term_taxonomy_id" 20 has_one :w_term, :through => :w_term_taxonomy
  40. 40. If you need to know more… • http://codex.wordpress.org/Database_Description • http://code.tutsplus.com/tutorials/understanding- and-working-with-data-in-wordpress--cms-20567
  41. 41. And we made a gem • wpdb_activerecord: https://github.com/hothero/ wpdb_activerecord • It’s a ORM wrapper for the WordPress database, using ActiveRecord.
  42. 42. wpdb_activerecord 1 # Gemfile 2 gem "wpdb_activerecord" 3 4 # Post 5 WPDB::Post.all # Get all posts 6 @post = WPDB::Post.find(75) 7 @post.tags 8 @post.attachments # No matter what type 9 @post.revisions 10 @post.author 11 12 # Term 13 WPDB::Term.tag # get all tags 14 WPDB::Term.category # get all categories
  43. 43. wpdb_activerecord - advanced 1 # config/wpdb_activerecord.yml 2 WPDB_PREFIX: "cgjbugpbs_" # the table of WPDB::Post is cgjbugpbs_posts, not wp_posts 4 WPDB_USER_CLASS: "WUser" 5 6 # models/w_user.rb 7 class WUser < WPDB::User 8 def hello 9 puts "world" 10 end 11 end 12 13 # usage 14 @author = WPDB::Post.find(25).author 15 @author.class_name # will get WUser, not WPDB:: 16 User 17 @author.hello # world
  44. 44. wpdb - installation
  45. 45. wpdb - installation
  46. 46. wpdb - installation
  47. 47. wpdb - installation
  48. 48. wpdb - installation
  49. 49. wpdb -usage
  50. 50. wpdb -usage
  51. 51. wpdb -usage
  52. 52. wpdb -usage
  53. 53. wpdb -usage
  54. 54. wpdb -usage
  55. 55. wpdb -usage
  56. 56. wpdb -usage
  57. 57. Our Progress & Goal Backend
 +
 DB Schema Frontend
  58. 58. wpdb_activerecord Server Side Visitors i0.wp.com/…
  59. 59. Cloudflare - Page Rules
  60. 60. And we done pcu 6000 ⬆ NT$5000 ⬇ Monthly Data • 7 million pageview ⬆ • 1.2 hundred million requests ⬆ • 4 million UU ⬆
  61. 61. 2015/02
  62. 62. Our Progress & Goal Backend
 +
 DB Schema Frontend
  63. 63. CMS Admin Edit Flow Media Gallery Globalize Cronjob
  64. 64. editflow.org • Edit Flow gives you custom statuses, a calendar, editorial comments, and more, all to make it much easier for your team to collaborate within WordPress. • Calendar • Custom Statuses • Editorial Comments • Editorial Metadata • Notifications • Story Budget • User Groups
  65. 65. Editor Structure Author Senior
 Editor Chief
 Editor ready to 
 review ready to 
 check publish Normal Flow Editor
  66. 66. Edit Flow Calendar Custom Statuses Notifications
  67. 67. Editorial Comments • Threaded commenting in the admin for private discussion between writers and editors.
  68. 68. Editorial Comments • Use this gem: acts_as_commentable • Polymorphic Associations 1 commentable = Post.create 2 comment = commentable.comments.create 3 comment.title = "First comment." 4 comment.comment = "This is the first comment." 5 comment.save
  69. 69. What’s the Polymorphic Associations • Assume a situation • An employee has many pictures • A Product has many pictures • And each of those pictures have owned information detail.
  70. 70. What’s the Polymorphic Associations • In general: two relationship tables to associate objects and pictures Employee Product Employee_
 Relationship employee_id picture_id Product_
 Relationship product_id picture_id Picture
  71. 71. What’s the Polymorphic Associations • Level up: an additional table to associate Employee Product Object
 Relationship object_id picture_id Picture
  72. 72. What’s the Polymorphic Associations • Polymorphic Associations Employee Product Picture imageable_id imageable_type will be: * Employee * Product
  73. 73. What’s the Polymorphic Associations • Practice in Rails.
  74. 74. What’s the Polymorphic Associations • In migration
  75. 75. editflow.org • Edit Flow gives you custom statuses, a calendar, editorial comments, and more, all to make it much easier for your team to collaborate within WordPress. • Calendar • Custom Statuses • Editorial Comments • Editorial Metadata • Notifications • Story Budget • User Groups
  76. 76. Story Budget • View all of your upcoming posts in a more traditional story budget view, and hit the print button to take it to your planning meeting.
  77. 77. Search Design In General • In general, we maybe use many conditions to match different situation. 1 def search 2 @posts = Post.send(params[:scope]) 3 if params.key?(:author_id) 4 @posts = @posts.where(author_id: params[: 5 author_id]) 6 end 7 if params.key?(:post_type) 8 @posts = @posts.where(post_type: params[: 9 post_type]) 10 end 11 if params.key?(:start_date) || params.key?(: 12 end_date) 13 @posts = @posts.where(updated_at: params[: 14 start_date]..params[:end_date]) 15 end 16 # ... 17 end
  78. 78. Search Design In General • In general, we maybe use many conditions to match different situation. 1 def search 2 @posts = Post.send(params[:scope]) 3 if params.key?(:author_id) 4 @posts = @posts.where(author_id: params[: 5 author_id]) 6 end 7 if params.key?(:post_type) 8 @posts = @posts.where(post_type: params[: 9 post_type]) 10 end 11 if params.key?(:start_date) || params.key?(: 12 end_date) 13 @posts = @posts.where(updated_at: params[: 14 start_date]..params[:end_date]) 15 end 16 # ... 17 end https://github.com/ activerecord-hackery/ ransack
  79. 79. Ransack - View Helper1 <%= search_form_for @q do |f| %> 2 # Search if the name field contains... 3 <%= f.label :name_cont %> 4 <%= f.search_field :name_cont %> 5 6 # Search if an associated articles.title 7 starts with... 8 <%= f.label :articles_title_start %> 9 <%= f.search_field :articles_title_start %> 10 11 # Attributes may be chained. Search multiple 12 attributes for one value... 13 <%= f.label : 14 name_or_description_or_email_or_articles_t 15 itle_cont %> 16 <%= f.search_field : 17 name_or_description_or_email_or_articles_t 18 itle_cont %> 19 20 <%= f.submit %> 21 <% end %> name_cont
  80. 80. Ransack - View Helper1 <%= search_form_for @q do |f| %> 2 # Search if the name field contains... 3 <%= f.label :name_cont %> 4 <%= f.search_field :name_cont %> 5 6 # Search if an associated articles.title 7 starts with... 8 <%= f.label :articles_title_start %> 9 <%= f.search_field :articles_title_start %> 10 11 # Attributes may be chained. Search multiple 12 attributes for one value... 13 <%= f.label : 14 name_or_description_or_email_or_articles_t 15 itle_cont %> 16 <%= f.search_field : 17 name_or_description_or_email_or_articles_t 18 itle_cont %> 19 20 <%= f.submit %> 21 <% end %> articles_title_start
  81. 81. Ransack - View Helper1 <%= search_form_for @q do |f| %> 2 # Search if the name field contains... 3 <%= f.label :name_cont %> 4 <%= f.search_field :name_cont %> 5 6 # Search if an associated articles.title 7 starts with... 8 <%= f.label :articles_title_start %> 9 <%= f.search_field :articles_title_start %> 10 11 # Attributes may be chained. Search multiple 12 attributes for one value... 13 <%= f.label : 14 name_or_description_or_email_or_articles_t 15 itle_cont %> 16 <%= f.search_field : 17 name_or_description_or_email_or_articles_t 18 itle_cont %> 19 20 <%= f.submit %> 21 <% end %> name_or_description_or_email _or_articles_title_cont
  82. 82. Ransack - Controller 1 def index 2 @q = Person.ransack(params[:q]) 3 @people = @q.result(distinct: true) 4 end
  83. 83. Ransack - Controller 1 def index 2 @q = Person.ransack(params[:q]) 3 @people = @q.result(distinct: true) 4 end
  84. 84. In Practice q[status_scope] q[author_id_eq] q[post_type_eq] q[author_name_cont] q[updated_at_gteq] - q[updated_at_lteq]
  85. 85. editflow.org • Edit Flow gives you custom statuses, a calendar, editorial comments, and more, all to make it much easier for your team to collaborate within WordPress. • Calendar • Custom Statuses • Editorial Comments • Editorial Metadata • Notifications • Story Budget • User Groups
  86. 86. User Groups • Keep your users organized by department or function.
  87. 87. Editor Structure Author Senior
 Editor Chief
 Editor Editor
  88. 88. Maybe DB Schema User Author Editor Admin or User user_type
  89. 89. STI (Single-table inheritance) class User < ActiveRecord::Base end class Author < User enum role: [:normal, :blogger] def publish # ex: only author can use end end class Editor < User enum role: [:editor, :senior_editor, :chief] end class Admin < User end User type type: rails reserved word
  90. 90. STI with Priority Problem • STI is unfit for priority feature. • Chief Editor > Senior Editor > Editor > Author • Enum-design is more fit. 1 class User < ActiveRecord::Base 2 enum role: [:normal, :blogger, :editor, :senior_editor, :chief] 4 end
  91. 91. Other parts • Except edit-flow, there are some more features • takeover & editing lock • media gallery • globalize
  92. 92. A situation Author Editor wanna edit
  93. 93. takeover & editing lock • Use this gem: message_bus • MessageBus implements a Server to Server channel protocol and Server to Web Client protocol (using polling or long-polling)
  94. 94. • We use current_editor_id field as lock in post. • Subscribe a channel for takeover when start editing in front- end. • Publish a message to the channel when someone wanna edit. takeover & editing lock 1 MessageBus.start(); 2 MessageBus.callbackInterval = 500; 3 MessageBus.subscribe("/posts/<%= @post.id %>/takeover/request", 4 function(msg){ 5 unlock_post_and_auto_save(); 6 window.location = "<%= posts_path %>"; 7 }); 1 MessageBus.publish(“/posts/#{post.id}/takeover/request”, username: user.name) Channel
  95. 95. Media Gallery
  96. 96. Media Gallery - Tricks Browsers don't allow file uploads via XMLHttpRequest (aka XHR) for security reasons.
  97. 97. General in jQuery • Hijack the forms submit event to execute our custom iFrame-method function • Submit the form to the iFrame normal-style (non-AJAX) • Copy the response content from the iFrame back into the parent window. http://www.alfajango.com/blog/ajax-file-uploads-with-the-iframe-method/
  98. 98. remotipart • Use this gem: remotipart • Remotipart is a Ruby on Rails gem enabling AJAX file uploads with jQuery in Rails 3 and Rails 4 remote forms. 1 # Gemfile 2 gem "remotipart" 3 4 # js 5 //= require jquery.remotipart
  99. 99. Globalize
  100. 100. globalize • Use this gem: globalize • Each locale have their owned tags & revisions 1 # config/initializers/post_translation.rb 2 Post::Translation.module_eval do 3 acts_as_ordered_taggable 4 has_paper_trail only: [:content, :title, : 5 excerpt] 6 end
  101. 101. Mobile APP • http://apps.thenewslens.com/
  102. 102. API Design In General class ApiController < ApplicationController def all # get review & news type post case params[:post_type] when "new" # latest when "hot" # hot end end def review case params[:post_type] when "new" when "hot" end end end def news case params[:post_type] when "new" when "hot" end end
  103. 103. has_scope • Use this gem: has_scope • In model 1 class Graduation < ActiveRecord::Base 2 scope :featured, -> { where(:featured => true) 3 } 4 scope :by_degree, -> degree { where(:degree => 5 degree) } 6 scope :by_period, -> started_at, ended_at { 7 where("started_at = ? AND ended_at = ?", 8 started_at, ended_at) } 9 end
  104. 104. has_scope • You can use those named scopes as filters by declaring them on your controller and just need to call apply_scopes to an specific resource. 1 class GraduationsController < 2 ApplicationController 3 has_scope :featured, :type => :boolean 4 has_scope :by_degree 5 has_scope :by_period, :using => [:started_at, 6 :ended_at], : 7 type => :hash 8 9 def index 10 @graduations = apply_scopes(Graduation).all 11 end 12 end
  105. 105. has_scope • You can use those named scopes as filters by declaring them on your controller and just need to call apply_scopes to an specific resource. 1 class GraduationsController < 2 ApplicationController 3 has_scope :featured, :type => :boolean 4 has_scope :by_degree 5 has_scope :by_period, :using => [:started_at, 6 :ended_at], : 7 type => :hash 8 9 def index 10 @graduations = apply_scopes(Graduation).all 11 end 12 end /graduations?featured=true
  106. 106. has_scope • You can use those named scopes as filters by declaring them on your controller and just need to call apply_scopes to an specific resource. 1 class GraduationsController < 2 ApplicationController 3 has_scope :featured, :type => :boolean 4 has_scope :by_degree 5 has_scope :by_period, :using => [:started_at, 6 :ended_at], : 7 type => :hash 8 9 def index 10 @graduations = apply_scopes(Graduation).all 11 end 12 end /graduations?by_period[started_at]=20100701&by_period[ended_at]=20101013
  107. 107. has_scope • You can use those named scopes as filters by declaring them on your controller and just need to call apply_scopes to an specific resource. 1 class GraduationsController < 2 ApplicationController 3 has_scope :featured, :type => :boolean 4 has_scope :by_degree 5 has_scope :by_period, :using => [:started_at, 6 :ended_at], : 7 type => :hash 8 9 def index 10 @graduations = apply_scopes(Graduation).all 11 end 12 end /graduations?featured=true&by_degree=phd
  108. 108. Tragedy at the admin theme Find out a good design which have smooth operating and fancy
  109. 109. turbolinks & pjax • Instead of letting the browser recompile the JavaScript and CSS between each page change, it keeps the current page instance alive and replaces only the body (or parts of) and the title in the head. • Same advantages: good user experience, reduce bandwidth and server cost • In particular with Rails: • more detail: http://goo.gl/Lx7mHk # Gemfile gem “turbolinks” # app/assets/javascripts/ application.js //= require tubolinks $.pjax({url:’authors’, container:’#main’}) if request.headers[‘X-PJAX’] render:layout end
  110. 110. rails-gem-list • A workman must sharpen his tools if he is to do his work well / ⼯工欲善其事,必先利其器 • We’ve done a gem: rails-gem-list • You can go through rails-gem-list to know how to construct your project architecture and DB schema. Just like • acts_as_taggable • ransack • …
  111. 111. rails-gem-list • A workman must sharpen his tools if he is to do his work well / ⼯工欲善其事,必先利其器 • We’ve done a gem: rails-gem-list • You can go through rails-gem-list to know how to construct your project architecture and DB schema. Just like • acts_as_taggable • ransack • …
  112. 112. Finally • If you want to do a media website, you can follow edit-flow to manage your posts. • If your WordPress website becomes larger and larger, you can rewrite your front-end with Rails. • Please don’t even think to transfer the whole site from WordPress to Rails. • After we had spoken many topics, there are still two main parts we didn’t present • Server Architecture • Data Migration
  113. 113. Special Thanks X @dlackty @ymowov @baojjeu @st0012 @nanasyu @eugg @chentyphoon @randyhsieh @fufukwang Contact me: hothero@backer-founder.com

×