How do you add toastr-rails gem to Rails 6 project? - css

I am trying to add the toastr gem to my Rails 6 project. I also have the devise gem installed.
I do not understand webpacker and how to make toastr-rails webpacker friendly.
I have read all the documentation. Don't tell me to read the documentation.
This is what I've tried:
yarn add toastr
Then in my assets/packs/application.js file, I added:
#import 'toastr'
And in my assets/stylesheets/application.scss file, I added:
*= require_toastr
Finally my layouts/application.html.erb has this code:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<% unless flash.empty? %>
<script type="text/javascript">
<% flash.each do |f| %>
<% type = f[0].to_s %>
toastr['<%= type %>']('<%= f[1] %>');
<% end %>
</script>
<% end %>
<%= yield %>
</body>
</html>
I don't get the toast notifications.
I don't get any notifications.
But this code works on my Rails 4 project.

If you want to add toastr with toastr-rails gem, use asset pipeline instead of webpack.
Here are the steps to add toastr with the webpack.
Add toastr js with yarn
yarn add toastr
Require toastr in app/javascript/packs/application.js. I added it to the global to avoid errors
global.toastr = require("toastr")
Create app/javascript/stylesheets/application.scss file to import custom or library css files
Import toastr css in app/javascript/stylesheets/application.scss
#import 'toastr'
Import app/javascript/stylesheets/application.scss file in app/javascript/packs/application.js
import "../stylesheets/application"
I wrote a helper method for flash messages. Add this method to application_helper.rb or another helper
def toastr_flash
flash.each_with_object([]) do |(type, message), flash_messages|
type = 'success' if type == 'notice'
type = 'error' if type == 'alert'
text = "<script>toastr.#{type}('#{message}', '', { closeButton: true, progressBar: true })</script>"
flash_messages << text.html_safe if message
end.join("\n").html_safe
end
Add toastr_flash method to layouts/application.html.erb or wherever you want
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<%= yield %>
<%= toastr_flash %>
</body>
</html>

first you need to add toastr to your project
using yarn
yarn add toastr
using npm
npm -i toastr
after that you can see in your node_modules the file toastr (node_modules/toastr) inside that have the toastr.scss file and toastr.js file, well let's import it
app/assets/application.scss
#import "toastr/toastr";
app/javascripts/packs/application.js
toastr = require("toastr")
or
import toastr from 'toastr/toastr';

Related

How do I include my company's global styles CDN (for dev use) using Webpack, within a Vue cli project?

I've tried importing via the entry file (main.js)...
import Vue from 'vue'
import App from '#/App'
import router from '#/router/router'
import store from '#/store/store'
import BootstrapVue from 'bootstrap-vue'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
import { Popover } from 'bootstrap-vue/es/directives'
import 'https://mycompany/main.min.css'
Vue.use(BootstrapVue)
Vue.use(Popover)
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
store,
router,
template: '<App/>',
components: { App }
})
I've tried to find a place within webpack.base.config (externals or publicPath) via numerous posts online - but none answered my question enough to make it work...
The css file delivered over the CDN essentially uses (and thus overwrites) Bootstrap classes, so it needs to be injected into the after Bootstrap - can I do this with my current setup? Vue/Webpack.. or do i need a task runner like Gulp? It's not enough to inject the cdn once we've built the project and have dist files.. we need to see the style changes whilst dev's work on the project.
Is there an easier way than either of those 2 methods, and before anyone asks - no.. they won't make it an npm package due to privacy/security.
The easy way would be to just include it in your index.html after all other Styles.
Btw: you can publish private repos on npm.
One way to do it is directly handling the template used by HtmlWebpackPlugin.
First disable inject in build/webpack.prod.conf:
//...
new HtmlWebpackPlugin({
//...
inject: false,
//...
})
//...
And in your index.html:
<!DOCTYPE html>
<html>
<head>
<!-- ... -->
<% if (process.env.NODE_ENV === 'production') { %>
<% for (file of htmlWebpackPlugin.files.css) { %>
<link rel="stylesheet" href="<%= file %>">
<% } %>
<link rel="stylesheet" href="https://mycompany/main.min.css">
<% } %>
</head>
<body>
<!-- ... -->
<div id="app"></div>
<% if (process.env.NODE_ENV !== 'production') { %>
<!-- During development there's less of a problem with putting stylesheets in the body -->
<link rel="stylesheet" href="https://mycompany/main.min.css">
<% } else{ %>
<% for (file of htmlWebpackPlugin.files.js) { %>
<script src="<%= file %>" type="text/javascript"></script>
<% } %>
<% } %>
</body>
</html>
What this does is inserting the static files manually, so you can choose the order, in production. During development, the link is written in the body tag, as then there isn't much of an issue with keeping standards.

Assets loaded but not applied in rails 4

I've just created a test project and been reading about the assets pipeline. So far, the assets are being loaded but not applied, as if I go to localhost:3000/assets/application.css I see the style I've written but I don't see the rules applied to the DOM.
Rails version: 4.2.1
Ruby version: 2.2.0
The structure is the following:
app
--- assets
------ images
------ javascripts
------ stylesheets
------------ application.css
------------ todos.css
The content of application.css is the following:
/*
*= require_tree .
*= require_self
*/
The content of application.js the following:
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require_tree .
The rails APP is very simple, as it's just a model (todo.rb), the controller for that model (todos_controller.rb) with the following content:
class TodosController < ActionController::Base
def index
#todos = Todo.all
end
end
Very simple, and for the view I'm using Slim templates with the following hierarchy:
app
--- views
------ todos
--------- index.slim
The content of application.html.erb is the following:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
</head>
<body>
<%= yield %>
</body>
</html>
And for the view:
.todos
- #todos.each do |todo|
.title = todo.title
.content = todo.content
Is there about the assets pipeline I'm missing? Thanks in advance.
Rename index.slim into index.html.slim.
P.S. convention over configuration
The TodosController must inherit from ApplicationController, not from ActionController::Base
class TodosController < ApplicationController
def index
#todos = Todo.all
end
end

Error on using Bootstrap Sass in rails

I'm working on a simple ruby on rails application and I am getting the following error:
TypeError: Cannot read property 'process' of undefined (in/home/saasbook/Documents/projects/Bookkeeper/app/assets/stylesheets/application.css.sass)
The Extracted source is as follows:
<html>
<head>
<title>Bookkeeper</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> //Highlighted error line in extract
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
This error occurred after I added Bootstrap Sass by Using the Bootstrap Sass plugin and following this tutorial
Below the extract its stated that the error is at:
app/views/layouts/application.html.erb:5:in_app_views_layouts_application_html_erb__226809778_88444660'
My code
application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Bookkeeper</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> //Highlighted error line in extract
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
</head>
<body>
<%= yield %>
</body>
</html>
application.css.sass
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
* compiled file so the styles you add here take precedence over styles defined in any styles
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
* file per style scope.
*
*= require_tree
*= require_self
*/
#import "bootstrap-sprockets"
#import "bootstrap"
The page shows this title in the red border on top, is this any help?
ExecJS::ProgramError in Portal#index
There seems to be an issue with version 5.0 of the autoprefixer-rails gem. Try downgrading to 4.0.2.2.
https://github.com/ai/autoprefixer-rails/issues/47
This will pop up if you are using Node instead of RubyRacer as your JS runtime.
EDIT -
This has been fixed in the latest version of autoprefixer.
bundle update autoprefixer-rails
This has been fixed in the latest release of autoprefixer. Upgrade using the following command -
bundle update autoprefixer-rails

Rails default layout file ignored

I was under the impression that if you had file named application.html.erb in your layouts directory that this layout would be applied automatically to all views without having to explicitly refer to it.
This doesn't appear to be the case.
I have one 'home' controller and it has one 'index' method:
class HomeController < ActionController::Base
def index
end
end
and the related home.html.erb view page:
<h2>Welcome!</h2>
<div>Stay tuned for basic functions to start arriving on this site.</div>
<div>The site will not look very stylish until one of the bounties gets done about writing the Style guide.</div>
and finally the application.html.erb file located in layouts:
<!DOCTYPE html>
<html>
<head>
<title>App Title</title>
<%= stylesheet_link_tag "application", media: "all" %>
</head>
<body>
<div class="navbar">
<div class="navbar-inner">
Categories
</div>
</div>
<%= yield %>
<div class="footer">Michael</div>
</body>
</html>
The above file was ignored until I added an explicit reference to the layout in my home controller like this:
class HomeController < ActionController::Base
layout 'application'
def index
end
end
What gives? I don't want to have to name the layout I am using in every controller. That was the point of having it at the application level.
The issue is you are inhering from ActionController::Base. You need to subclass from ApplicationController to ask Rails to use "application" layout as the default.
class HomeController < ApplicationController
def index
end
end

Ruby on Rails 3 CSS only for certain Views (Devise)

I am quite new to Ruby on Rails and wanted to place my custom CSS file into the Devise (Sign Up View). I placed my global CSS into the application.js (Asset Pipeline) and placed 2 Helper functions in my
helpers/application_helper.rb
def javascript(*files)
content_for(:head_javascript) { javascript_include_tag(*files) }
end
def stylesheet(*files)
content_for(:head_stylesheet) { stylesheet_link_tag(*files) }
end
and my views/layouts/application.html.erb
<!DOCTYPE html>
<%
if (controller.controller_name == "sessions") && (controller.action_name == "new")
javascript 'theme/signup'
stylesheet 'theme/signup'
end
%>
<html>
<head>
<title>Mysite</title>
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js" type="text/javascript"></script>
<![endif]-->
<%= yield(:head_stylesheet) %>
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= yield(:head_javascript) %>
<%= csrf_meta_tags %>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<%= yield %>
</body>
</html>
Then I generated the Devise Views and adjusted my twitter bootstrap form
rails generate devise:views
And now want to place my signup.css inside the Signup View, but how?
So I created the Devise Controllers, to use my helper methods:
bash <(curl -s https://raw.github.com/foohey/cdc/master/cdc.sh)
Now I am stuck, because I my helpers donĀ“t work with:
<%
if (controller.controller_name == "sessions") && (controller.action_name == "new")
javascript 'theme/signup'
stylesheet 'theme/signup'
end
%>
Is there an easy way in rails to handle custom css files? I am new to the asset pipeline concept and it is a bit confusing.
Thanks for help.
Have you heard about content_for? It is really useful for things like that. Inside you layout add:
<%= yield :head %>
inside your head tag. Then you can write the following inside the view (devise/sessions/new):
<% content_for :head do %>
javascript 'theme/signup'
stylesheet 'theme/signup'
<% end %>
This will perfectly separate your layout from single view concerns, and it should also fix the problem you're having.
You can place your custom css files in the css directory inside the public directory and inside the <head> tags of the view you want the custom css files to be you do this
<%= stylesheet_link_tag '/css/signup' %>
The signup.css will only be available to the signup view assuming that's where you place your stylesheet_link_tag
I think you want something like these:--
<% if (controller.controller_name == "sessions") && (controller.action_name == "new")%>
<%= stylesheet_link_tag "theme/signup"%>
<%= javascript_include_tag "theme/signup" %>
<% end %>

Resources