How To Build a Blog using Froala-WYSIWYG
Introduction
Hello, in this tutorial I will show you how to build a blog. For our blog, we will make use of clearance
for user authentication and Froala-WYSIWYG to provide a rich editor that will enable us to style our contents. Let's dig into it.
Rails Application Setup
First, let us start with creating our application. Run the command below, for the purpose of this tutorial, I will call mine froala-blog
.
rails new froala-blog -T
The -T
flag tells Rails to create a new application without the default test suite.
Open your Gemfile
and add the following gems.
#Gemfile
...
gem 'clearance'
gem 'bootstrap-sass'
Clearance is a simple authentication tool built for Rails. You will be using it for authentication on the blog you will be building. The other gem - bootstrap-sass
will enable you to style your application using Bootstrap.
Now install the gem by running bundle install
from your terminal.
Using your text editor, rename assets/stylesheets/application.css
to assets/stylesheets/application.scss
. Then apphend the line below:
#assets/stylesheets/application.scss
...
@import 'bootstrap-sprockets';
@import 'bootstrap';
Once that is done, you need to run the generator for clearance
. Run the command below from your terminal.
rails generate clearance:install
It will generate the following output on your terminal:
create config/initializers/clearance.rb
insert app/controllers/application_controller.rb
create app/models/user.rb
create db/migrate/20161231132513_create_users.rb
*******************************************************************************
Next steps:
1. Configure the mailer to create full URLs in emails:
# config/environments/{development,test}.rb
config.action_mailer.default_url_options = { host: 'localhost:3000' }
In production it should be your app's domain name.
2. Display user session and flashes. For example, in your application layout:
<% if signed_in? %>
Signed in as: <%= current_user.email %>
<%= button_to 'Sign out', sign_out_path, method: :delete %>
<% else %>
<%= link_to 'Sign in', sign_in_path %>
<% end %>
<div id="flash">
<% flash.each do |key, value| %>
<div class="flash <%= key %>"><%= value %></div>
<% end %>
</div>
3. Migrate:
rake db:migrate
*******************************************************************************
Clearance does a lot of heavy lifting for us that we will not dive into in this tutorial. You can check out its Github repository to see all it has to offer.
Let us implement the steps shown to us above.
Using your text editor navigate to config/environments/development.rb
, and add the line below;
#config/environments/development.rb
...
config.action_mailer.default_url_options = { host: 'localhost:3000' }
...
Add it just above the end
delimiter.
Create a new file called _navigation.html.erb
in your views/layouts
directory. You will use this for our navigation. Paste the code below into the newly created file:
#views/layouts/_navigation.html.erb
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Froala-Blog</a>
</div>
<div class="collapse navbar-collapse" id="navbar-collapse">
<ul class="nav navbar-nav navbar-right">
<li><%= link_to 'Home', root_path %></li>
<% if signed_in? %>
<li><%= link_to 'New Article', new_article_path %></li>
<li>Signed in as: <%= current_user.email %></li>
<li><%= link_to 'Sign out', sign_out_path, method: :delete %></li>
<% else %>
<li><%= link_to 'Sign in', sign_in_path %></li>
<% end %>
</ul>
</div>
</div>
</nav>
Navigate to views/layouts/application.html.erb
and make yours look like this:
#views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>FroalaBlog</title>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
<body>
<%= render "layouts/navigation" %>
<div id="flash">
<% flash.each do |key, value| %>
<div class="flash <%= key %>"><%= value %></div>
<% end %>
</div>
<div class="container-fluid">
<%= yield %>
</div>
</body>
</html>
Installing Froala
Open up your Gemfile
and add the following gems:
#Gemfile
...
gem 'simple_form'
gem 'wysiwyg-rails'
The first is a gem that allows us to easily make forms in Rails. The next is the gem for Froala-WYSIWYG.
Run bundle install
.
You need to import some assets into your application.
Add the code below to your app/assets/stylesheets/application.scss
, just above the *= require_tree .
line.
#app/assets/stylesheets/application.scss
...
*= require froala_editor.min.css
*= require froala_style.min.css
*= require font-awesome
...
For your app/assets/javascripts/application.js
, add the code:
#app/assets/javascripts/application.js
...
//= require froala_editor.min.js
...
Now you have Froala-WYSIWYG all set up
Creating Articles Controller and Model.
Open your terminal and run the command to generate your ArticlesController
.
rails generate controller Articles
This will generate a bunch of files and directories for us.
Navigate to app/controllers/articles_controller.rb
and paste in the code below:
#app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
before_action :find_article, only: [:edit, :update, :show, :delete]
before_action :require_login, except: [:index, :show]
def index
@articles = Article.all
end
# New action for creating article
def new
@article = Article.new
end
# Create action saves the article into database
def create
@article = Article.new(article_params)
if @article.save
flash[:notice] = "Successfully created article!"
redirect_to article_path(@article)
else
flash[:alert] = "Error creating new article!"
render :new
end
end
# Edit action retrives the article and renders the edit page
def edit
end
# Update action updates the article with the new information
def update
if @article.update_attributes(article_params)
flash[:notice] = "Successfully updated article!"
redirect_to article_path(@article)
else
flash[:alert] = "Error updating article!"
render :edit
end
end
# The show action renders the individual article after retrieving the id
def show
end
# The destroy action removes the article permanently from the database
def destroy
if @article.destroy
flash[:notice] = "Successfully deleted article!"
redirect_to articles_path
else
flash[:alert] = "Error updating article!"
end
end
private
def article_params
params.require(:article).permit(:title, :body)
end
def find_article
@article = Article.find(params[:id])
end
end
In the code above, we have all the actions needed to create an article.
The line:
before_action :require_login, except: [:index, :show]
Restricts unauthorized users from editing, deleting, or creating a new article.
Let us set up our views, create the needed files by running these commands:
touch app/views/articles/_form.html.erb
touch app/views/articles/index.html.erb
touch app/views/articles/show.html.erb
touch app/views/articles/new.html.erb
touch app/views/articles/edit.html.erb
Paste the code below into the respective files.
The code for our form:
#app/views/articles/_form.html.erb
<%= simple_form_for (@article) do |f| %>
<% if @article.errors.any? %>
<div id="error_explanation">
<h2>
<%= "#{pluralize(@article.errors.count, "error")} prohibited this post from being saved:" %>
</h2>
<ul>
<% @article.errors.full_messages.each do |msg| %>
<li>
<%= msg %>
</li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-group">
<%= f.input :title, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :body %>
<%= f.text_area :body, id: "wysiwyg" %>
</div>
<div class="form-group">
<%= f.button :submit %>
</div>
<% end %>
<!-- script for FROALA-WYSIWYG -->
<script>
$('#wysiwyg').froalaEditor({
inlineMode: false,
heightMin: '200px',
toolbarButtons: ['bold', 'italic', 'underline'],
})
</script>
The main things that stand out in the code above are:
id: "wysiwyg"
And:
<script>
$('#wysiwyg').froalaEditor({
inlineMode: false,
heightMin: '200px',
toolbarButtons: ['bold', 'italic', 'underline'],
})
</script>
These two are very important for Froala-WYSIWYG to work. Let's make progress.
Edit Page
#app/views/articles/edit.html.erb
<h2>Edit Article</h2>
<!-- Renders the form located at app/views/articles/_form.html.erb -->
<%= render "articles/form" %>
Index Page
#app/views/articles/index.html.erb
<div class="container">
<div class="col-sm-10 col-sm-offset-1 col-xs-12">
<% @articles.each do |article| %>
<div class="col-xs-12 text-center">
<div class="text-center">
<h2><%= article.title %></h2>
<h6><%= article.created_at.strftime('%b %d, %Y') %></h6>
</div>
<div>
<%= raw(article.body).truncate(358) %>
</div>
<div class="text-center">
<%= link_to "READ MORE", article_path(article) %>
</div>
<!-- This block is available to only signed in users -->
<% if signed_in? %>
<%= link_to "Show", article_path(article), class: "btn btn-primary" %>
<%= link_to "Edit", edit_article_path(article), class: "btn btn-default" %>
<%= link_to "Delete", article_path(article), class: "btn btn-danger", data: {:confirm => "Are you sure?"}, method: :delete %>
<% end %>
<hr />
</div>
<% end %>
</div>
</div>
New Article Page
#app/views/articles/new.html.erb
<h2>Create New Article</h2>
<!-- Renders the form located at app/views/articles/_form.html.erb -->
<%= render "articles/form" %>
Show Page
#app/views/articles/show.html.erb
<div class="col-sm-11 col-xs-12">
<h2 class="text-center"><%= @article.title %></h2>
<h5 class="text-center"><%= @article.created_at.strftime('%b %d, %Y') %></h5>
<div class="fr-view"><%= raw @article.body %></div>
</div>
In the code for the show page, you will see that the body of the articles is rendered in a div
whose class is fr-view
. Froala-WYSIWYG requires this to be like so if you want the styles to be shown on the page.
With all these done, let us set up our routes. Here is what your routes should look like:
#config/routes.rb
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
root to: "articles#index"
resources :articles
end
Finally, you need to generate your Article model. Run the command to do so.
rails generate model Article title:string body:text
Next migrate your database.
rake db:migrate
You can now view your new blog. Start up your server rails server
, point your browser to http://localhost:3000
to see what you have.
Conclusion
In this tutorial, you learned about Clearance and Froala-WYSIWYG. I hope you enjoyed it.
So nice article! But, ArticlesController in second line,
before_action :find_article, only: [:edit, :update, :show, :delete]
is wrong.
You probably want to write
before_action :find_article, only: [:edit, :update, :show, :destroy]
And if you add plugin, editor becomes more cool!
[application.js]
âŠ
// add some plugin
//= require plugins/align.min.js
//= require plugins/char_counter.min.js
//= require plugins/code_beautifier.min.js
//= require plugins/code_view.min.js
//= require plugins/colors.min.js
//= require plugins/emoticons.min.js
//= require plugins/entities.min.js
//= require plugins/file.min.js
//= require plugins/font_family.min.js
//= require plugins/font_size.min.js
//= require plugins/fullscreen.min.js
//= require plugins/image.min.js
//= require plugins/image_manager.min.js
//= require plugins/inline_style.min.js
//= require plugins/line_breaker.min.js
//= require plugins/link.min.js
//= require plugins/lists.min.js
//= require plugins/paragraph_format.min.js
//= require plugins/paragraph_style.min.js
//= require plugins/quick_insert.min.js
//= require plugins/quote.min.js
//= require plugins/save.min.js
//= require plugins/table.min.js
//= require plugins/url.min.js
//= require plugins/video.min.js
//= require languages/[each_favorite_language].js
[application.scss]
âŠ
// add some plugin
@import âplugins/char_counter.min.cssâ;
@import âplugins/code_view.min.cssâ;
@import âplugins/colors.min.cssâ;
@import âplugins/emoticons.min.cssâ;
@import âplugins/file.min.cssâ;
@import âplugins/fullscreen.min.cssâ;
@import âplugins/image_manager.min.cssâ;
@import âplugins/image.min.cssâ;
@import âplugins/line_breaker.min.cssâ;
@import âplugins/quick_insert.min.cssâ;
@import âplugins/table.min.cssâ;
@import âplugins/video.min.cssâ;
Thank you for your great article!
Thanks a lot, Kingsley! Great tutorial, especially for beginners. Would be awesome to have another one about writing emails using Froala editor, thatâs what really gives me headaches right now. Many kudos to you đ