wicked pdf rendering css / javascript in Ruby - ruby

I'm trying to convert html page with wicked pdf but the html / css / javascript are not displayed.
Here is my controller :
respond_to do |format|
format.html
format.pdf do
render :pdf => 'rapport_pdf',
:template => 'messages/template_load_pdf.pdf.erb',
:layout => 'rapport_load_pdf.html.erb',
:show_as_html => params[:debug].present?
end
end
Here is my rapport_load_pdf.html.erb :
<!DOCTYPE html>
<html>
<head>
<title>PDF</title>
<%= wicked_pdf_stylesheet_link_tag "application" -%>
</head>
<body>
<div class='container'>
<%= yield %>
</div>
</body>
Here is my gemfile :
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary'

I have tried different techniques to speedup my pdf generation. But these steps were pretty helpful.
Try using font-awesome-rails and bootstrap ruby gem
Use separate scss file to import necessary css/scss files. And, Try to avoid importing unnecessary css files. (Because loading external css files and images kills the server memory and delay the pdf process.)
Please see the sample code below
Import your stylesheet in the pdf layout file as bellow.
<%= wicked_pdf_stylesheet_link_tag "pdf_layout", media: "all" -%>
Please check more details here

Related

javascript_include_tag not working in rails 2?

The rails tag to include javascript , and for browser caching:
<%= javascript_include_tag '/skin/js/html5.js', :cache => true %>
forget about caching simple javascript_include tag is also not working.
Ex:
<%= javascript_include_tag '/skin/js/html5.js', :cache => true %>
But the script tag below is working find stop working after doing this.
<script src="/skin/js/html5.js" type="text/javascript"></script>
using Rails 2 any reason for such a behavior or this tag did not even work in rails2?
Try
First make sure that you are including the tag inside the head
<% content_for :head do %>
<script src="skin/js/html5.js"></script>
<% end %>

While learning Ruby, Sinatra, working on a project, yield error happened

In my project, I have a few files:
1. main.rb
require 'sinatra'
set :public_folder, 'public'
set :views, 'views'
set :erb, :layout => :base
get '/' do
erb :layout
end
get '/about' do
erb :about
end
get '/contact' do
erb :contact
end
2. layout.erb
<% title="Songs By Sinatra" %>
<!doctype html>
<html lang="en">
<head>
<title>
<%=title %>
</title>
<meta charset="utf-8">
</head>
<body>
<header>
<h1><%= title %></h1>
<nav>
<ul>
<li>Home
</li>
<li>About
</li>
<li>Contact
</li>
</ul>
</nav>
</header>
<section>
<%=yield %>
</section>
</body>
</html>
<p>Welcome to this website that's all about the songs of the great Frank Sinatra.</p>
<img src="/images/sinatra.jpg" alt="Frank Sinatra">
3. about.erb
<p>
This site is a demonstration of how to build a website using Sinatra.
</p>
When I go to http://localhost:4567/about everything is OK, page loads, but when I go to http://localhost:4567/, I get an error: no block given (yield).
Can anyone explain what is the problem, and possible solution.
Thank you very much in advance.
You need to pass a block in
erb :layout
For <%=yield %> in layout.erb to work, you need to pass a block whose output will be placed at the location of `yield. In its simplest form, you can do something like this:
erb :layout { "This is what I want in output" }
Typically, you render another template:
erb :layout do
erb :about
end
More details in documentation.
TLDR; what #wandmaker says - you need to pass a block to :layout.
Understanding yield is essential for understanding Ruby. Basically, yield passes control from one scope to another. All methods in Ruby accept blocks but they ignore them unless they explicitly yield or call them:
"A RUBY STRING".downcase { p "I'm in a block!" }
# => "a ruby string"
But if the method calls yield, control is passed to the block and then passed back to the calling scope:
def yield_me
yield
end
yield_me { p "I'm in a block!" }
# => "I'm in a block!"
Alternatively, you can catch blocks as arguments:
def catch_me(&block)
block.call
end
catch_me { p "I'm in a block" }
# => "I'm in a block!"
So with that in mind, it should be clearer what your Sinatra template is doing - it renders layout.erb but when it hits yield, it tries to yield control to a block - in this case a non-existent one.
So all your responses should supply a block or sub-template like:
erb :layout { "<p>This is the about page</p>" }
or
erb :index

Beego template render partials

Is there a functionality to render partial templates in the Beego? I used this functionality in RoR.
Ruby on Rails partials:
Partial templates - usually just called "partials" - are another device for breaking the rendering process into more manageable chunks. With a partial, you can move the code for rendering a particular piece of a response to its own file.
Example from RoR:
<!-- html.erb -->
<h1>New zone</h1>
<%= render partial: "form", locals: {zone: #zone} %>
and
<!-- _form.html.erb -->
<%= form_for(zone) do |f| %>
<p>
<b>Zone name</b><br>
<%= f.text_field :name %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
Yes, though they are not explicitly referenced as partials in the documentation, you can compose templates like you described.
From the documentation for views.
{{template "header.html"}}
Logic code
{{template "footer.html"}}
Because Beego is an MVC framework, it will automatically look for your "partials" in the views directory.
If you had another subdirectory called views/base then your partial would look like this:
{{template "base/header.html" .}}
A good reference implementation that will provide more examples in the context of a real world app, check out the wetalk project on github

yield :content doesn't show content_for :content

I think I have the same issue with this.
Using multiple yields to insert content
And I tried the solution. I tried to have <%= yield :content %> in my application.html.erb and have content_for :content and the yield inside, in my view. But it is not working on my app. Can you please explain more or give sample scenario on my problem?
The links inside, must not reload, so I will not use render partial on every template I will display.
I just recently started learning Rails so it was all a little bit confusing for me. Thank you.
I tried this; this is just an example I will fix the connection of sidebar later.
in my applicaion.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Clinks</title>
<%= stylesheet_link_tag "application", media: "all" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
<body>
<section id="container" >
<%= render 'layouts/header' %>
<%= render 'layouts/sidebar' %>
<section id="main-content">
<section class="wrapper">
<div class="row">
<!-- %= yield % -->
<%=yield(:content) %>
</div><!--/row -->
</section><!--/wrapper -->
</section><!--/main-content -->
</section><!--/container -->
</body>
</html>
in my menu_tables.html.erb inside layouts folder.
<% content_for(:content) do %>
<%= render 'menu_tables/sidemenu' %>
<%= yield %>
<% end %>
<%= render template: "layouts/application" %>
in my routes.rb
Rails.application.routes.draw do
root :to => 'pages#home'
resources :menu_tables, except: [:show]
end
then in _sidemenu.html.erb under menu_tables controller is the code for the links, so each links from sidebar have different sidemenu.
May be you need to tell your controller to use layout 'menu'. In the link you provided names of the controller and layout matched, so it worked 'magically'.
See guides:
2.2.14 Finding Layouts
To find the current layout, Rails first looks for a file in
app/views/layouts with the same base name as the controller. For
example, rendering actions from the PhotosController class will use
app/views/layouts/photos.html.erb (or
app/views/layouts/photos.builder). If there is no such
controller-specific layout, Rails will use
app/views/layouts/application.html.erb or
app/views/layouts/application.builder. If there is no .erb layout,
Rails will use a .builder layout if one exists. Rails also provides
several ways to more precisely assign specific layouts to individual
controllers and actions.
(Note: you can check what layout is used in logs, look for line similar to Rendered menu_items/index.html.erb within layouts/application)

Sinatra static assets are not found when using rackup

I have a simple Sinatra app that is configured using the modular style. When I start the app using rackup -p 4567 as recommended in the readme file, the static assets in the public folder are not served. But when I start it using shotgun ./config.ru -p 4567 then they are served. Why does this happen? Could this happen in production?
Here is my code:
# config.ru
require 'rubygems'
require 'bundler'
require 'sinatra'
require 'jammit'
Bundler.require
Jammit.package!
require File.expand_path('./stick.rb')
run Stick
and this is the app ruby file
require 'sinatra/base'
class Stick < Sinatra::Base
get '/' do
haml :index
end
end
Looks like there are two good answers to this one (neither of the existing ones worked for me).
First off, in your config.ru file, you can include the following:
# Replace the directory names to taste
use Rack::Static, :urls => ['/stylesheets', '/javascripts'], :root => 'public'
Alternatively, if you're running your app via rackup, the :static option is set to false by default. You can remedy this by the following incantation:
class MyApp < Sinatra::Base
set :static, true
# ...
end
I had the same problem and i solved like this.
I have added this line in my config.ru .
map "/public" do
run Rack::Directory.new("./public")
end
And i use the static files in my views like this
%link{:type => 'text/css', :rel => 'stylesheet', :href => '/public/css/reset.css'}
%link{:type => 'text/css', :rel => 'stylesheet', :href => '/public/css/text.css'}
%link{:type => 'text/css', :rel => 'stylesheet', :href => '/public/css/960.css'}
%link{:type => 'text/css', :rel => 'stylesheet', :href => '/public/css/app.css'}
Not positive, but you may need to set :root, Stick.root?
(Based on How to deploy a modular Sinatra app to Heroku?)
In order for me to get this working on a new Sinatra app launched via config.ru, I had to do two of the things suggested in the other answers:
class MyApp < Sinatra::Base
set :static, true
set :root, File.dirname(__FILE__)
end
First create a folder named "public" in your sinatra project, then add a couple of folders
stylesheets
javascripts
images
Add your CSS, JS and or JPG,PNG (images) to each folder
Finally as #sirfilip says add below lines to config.ru file
map "/public" do
run Rack::Directory.new("./public")
end
If generic Sinatra (no framework default)
views/layout.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
...
<link rel="stylesheet" href="stylesheets/your_file.css">
<link rel="icon" type="image/ico" href="images/your_image.ico" />
</head>
<body>
<%= yield %>
...
<script src="javascripts/your_js.js"></script>
views/index.erb
<div class="margin-bottom-30">
<div class="row">
<div class="col-md-12">
<ul class="nav nav-pills">
<li class="active">Home <span class="badge">42</span></li>
<li>...</li>
</ul>
</div>
</div>
</div>
All of you images, stylesheets and javascripts will be available for any url registered in your Sinatra app , problem solved!

Resources