Rendering a Navbar React Component in Rails App - ruby-on-rails

I have a simple Rails 5 app with the react-rails gem installed. I want to create a Navbar that will appear at the top of every page in my app. I'm new to React, so normally what I would do is include an erb tag in application.html.erb that would render a layout helper called _navbar.html.erb, and would appear above the yield block. How do I accomplish this same thing using the react-rails gem and a navbar component? Rendering a react component from application.html.erb like this does not seem to be working:
<body>
<div id='app'>
<%= react_component 'Navbar' %>
<%= yield %>
</div>
</body>
Maybe it has something to do with <%= javascript_include_tag 'application' %> in application.html.erb being inside <head> and the page not being fully rendered yet. Any help would be appreciated (bonus points for including the react-bootstrap navbar component!) Thanks!
Edit: I can now get something to display, but it's not formatted like a navbar. I'm using the react-bootstrap docs example but no luck yet.

Related

ChartKick charts do not show when rendering to PDF using Wicked_PDF

I am using Rails 4, Wicked_PDF and Chartkick Gem's
For Google Charts I use:
<%= javascript_include_tag
"//www.google.com/jsapi", "chartkik" %>
The html view comes up with charts and everything as expected.
When I append .pdf to the url the pdf document shows in the browser but the ChartKick charts do not show.
The following error appears where the chart should be:
Error Loading Chart: No adapter found
I have found the following online in the PDFKit documentation.
Resources aren't included in the PDF: Images, CSS, or JavaScript does
not seem to be downloading correctly in the PDF. This is due to the
fact that wkhtmltopdf does not know where to find those files. Make
sure you are using absolute paths (start with forward slash) to your
resources. If you are using PDFKit to generate PDFs from a raw HTML
source make sure you use complete paths (either file paths or urls
including the domain). In restrictive server environments the root_url
configuration may be what you are looking for change your asset host.
I am assuming that wkhtmltopdf is not finding the link to the charts, but I am not sure how to fix this.
Does anyone have a suggestion?
I found this link:
Render jQuery in wicked_pdf
Where Unixmonkey helps FattRyan to solve this for Highcharts.
Can anyone help how to set this wicked_pdf_javascript_include_tag so that Wicket_PDF will accept charts from Chartkick using Google charts?
You have to specify a protocol http or https when referencing to a CDN inside the pdf layout.
Also chartkick is served via the assets pipeline, so use wicked_pdf_javascript_include_tag instead.
Replace this line:
<%= javascript_include_tag "//www.google.com/jsapi", "chartkik" %>
With this:
<%= javascript_include_tag "https://www.google.com/jsapi" %>
<%= wicked_pdf_javascript_include_tag "chartkick" %>
That's how I do it in a project of mine.
Cheers.
I struggled with this for a bit and the other answers were only partially useful for me. I wanted to provide more detail for anyone in the future:
The 4 major things I did to fix this for us were:
(1) Not using the middleware approach and instead using one off ruby embedded pdfs based off of a PDF layout you create
#Example layout file
#app/views/layout/pdf.pdf.rb
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<%= wicked_pdf_stylesheet_link_tag "print" %> #print specific stylesheet
<%= yield :head %>
</head>
<body>
<h1>PDF Report</h1>
<%= yield %>
</body>
</html>
(2) using wicked_pdf's asset helpers to load ONLY the javascript we needed on those pages for assets we store in the app (all CDN based assets can be loaded with a normal javascript_include_tag)
#Example page template for a PDF you're downloading
#app/views/users/profile.pdf.erb
<% content_for :head do %>
<%= javascript_include_tag "some_cdn.com" %>
<%= wicked_pdf_javascript_include_tag "chartkick" %>
<% end %>
<p>All your pages content</p>
(3) using the javascript_delay option
#Use it universally from the initializer or on the specific PDF rendering in the controller
#config/initializers/wicked_pdf.rb
WickedPdf.config = {
javascript_delay: 3000,
other_options...
}
(4) pass the "discrete" axis option otherwise we only saw the axis and no data for time based charts (line/area/etc.)
#In the above template, wherever you render your chart
#app/views/users/profile.pdf.erb
<% content_for :head do %>
<%= javascript_include_tag "some_cdn.com" %>
<%= wicked_pdf_javascript_include_tag "chartkick" %>
<% end %>
<%= area_chart #data_retriever.time_based_data, discrete: true %>
<%= pie_chart #data_retriever.other_data %> # the default is discrete: false so no need for another option
Add the following to the top of the view your trying to convert to a pdf:
<%= wicked_pdf_javascript_include_tag "application", "chartkick" %>
I got it to work with Alex Villa's answer and from the answer to a similar question by installing the latest wkhtmltopdf version then specifying the javascript_delay option in the controller in step (3):
respond_to do |format|
format.html
format.pdf do
render pdf: "filename",
javascript_delay: 3000,
template: 'template_path.pdf.erb',
layout: 'pdf.html'
end
end
If someone gets the same issue with Rails 4 in 2019, then try to freeze chartkick version on 2.3.5. Because from the 3.0.0 version they removed support for Rails < 4.2. See
chartkick CHANGELOG
gem 'chartkick', '2.3.5'
Add this at the beginning of head in your pdf view file:
<%= javascript_include_tag "https://www.google.com/jsapi" %>
<%= wicked_pdf_javascript_include_tag "chartkick" %>
And replace the wkhtmltopdf-binary gem with wkhtmltopdf-binary-edge. I used 0.12.4.0 version.
gem 'wkhtmltopdf-binary-edge', '0.12.4.0'
That's all I did and it worked.

Dynamically loaded assets in Rails 4 and Turbolinks

I am working on a Rails 4 app in application.html.erb I have the following code
....
<head>
<title>...</title>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
<%= yield :head %>
<%= csrf_meta_tags %>
</head>
What this does is allows me to load certain assets depending on the page I am on. So maybe in the show template of a certain action I could do something like
<% content_for :head do %>
<%= stylesheet_link_tag "show" %>
<% end %>
This works great and helps me keep the page structured clean and simple. The issue I am having now is that turbolinks is completely ignoring these assets and not even loading them when I click on a next link. I have looked around but cant seem to find an answer to this problem. Any help will be appreciated.
I had the same problem, try to add data-turbolinks-track into your stylesheet tag
This is most likely because turbolinks does not replace the <head> element:
Turbolinks makes following links in your web application faster. 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 and the title in the head. Think CGI vs persistent process.
As such, any changes to the <head> element will be ignored.

Modular page layout

I would like to display certain things on every or almost every page of my application. Things like header, footer, sidebar or navigation.
How would I go about doing that? I am coming from languages like PHP and ColdFusion where I would either include files or call a function to display what I want. I am having a hard time understanding how I can implement it in Rails.
Generally in your application layout, you use partials. A small example would look like
<body>
<%= render :partial => 'shared/header' %>
<%= yield %>
<%= render :partial => 'shared/footer' %>
</body>
Hope this helps.
Your application should have app/view/layouts/application.html.erb. That's where your html content goes.
In the application.html.erb, you should see <%= yield %>. This is where specific views for different controller actions with corresponding views go.
For your css files for application.html.erb, you should use app/assets/stylesheets/application.css.
For your javascript files for application.html.erb, you should use app/assets/javascripts/application.js.

RoR: How do I validate my pages when sometimes I have CSS links not in the HEAD?

I get this error when using the w3 validator: document type does not allow element "link" here
I mean, I know style links are suppossed to be in the head, but for an RoR project, it's more.. efficient? to only load what you need? cause, lets say, A stylesheet is loaded in a partial. and that partial is used on multiple pages. It makes sense, as far as DRYing things up goes, to include the stylesheet with the partial.
But it seems like DRYing things goes against W3C.
What do I do?
You shouldn't be putting <link> elements into your content like that. You can use ERB's blocks to yield the content into another part of your layout template, like this:
<% content_for :head do %>
<%= stylesheet_link_tag 'my_partial_styles' %>
<% end %>
<p>Your partial content...</p>
In your application layout, you can yield this content where it belongs:
<head>
<%= yield :head %>
</head>

How to use an RoR application template and still be able to add things to the html head?

I'm learning RoR through this tutorial. In tute, an application.html.erb file is created in views/layouts. In the body, a content div is created, and the <%= yield %> line is used. The other views that are created are then just inserted into the content div in the body of the application template.
But there are a few views that I have where I need to add some javascript to the head.
My question is, how can I use this structure, with a central application template, but also be able to put code into the head of the document? Thanks for reading.
Add <%=yield :header %> in your HTML head. Then, in a view:
<% content_for :header do %>
<!-- Javascript here //-->
<% end %>
<!-- Rest of the page here //-->
The bit in the content_for block will render where your yield :header is in your template.

Resources