Codementor Events

How To Build a Blog using Froala-WYSIWYG

Published Jan 10, 2017Last updated Jan 18, 2017
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.

Discover and read more posts from Kingsley Silas
get started
post comments2Replies
ăȘăœă˜ă‚“
6 years ago

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!

Mary
8 years ago

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 😀