How can use js.erb and json.erb templates in webpacker? - ruby-on-rails

The serviceworker-rails gem has a nice example of why I want to do this. tldr I can generate the manifest using asset helpers and loops.
// app/javascripts/packs/manifest.json.erb
<% icon_sizes = Rails.configuration.serviceworker.icon_sizes %>
{
"name": "My Progressive Rails App",
"short_name": "Progressive",
"start_url": "/",
"icons": [
<% icon_sizes.map { |s| "#{s}x#{s}" }.each.with_index do |dim, i| %>
{
"src": "<%= image_path "serviceworker-rails/heart-#{dim}.png" %>",
"sizes": "<%= dim %>",
"type": "image/png"
}<%= i == (icon_sizes.length - 1) ? '' : ',' %>
<% end %>
],
"theme_color": "#000000",
"background_color": "#FFFFFF",
"display": "fullscreen",
"orientation": "portrait"
}
I also want to inject other rubyland configs into my packfiles such as public keys and other runtime app settings that the js bundle should have. Default rails handles this case really well with erb. How can I do basically the same thing using webpack instead of sprockets?
I tried putting a json.erb in app/javascripts/packs but no go.

To have erb support, try rails webpacker:install:erb

I had the same issue and eventually rendered it using a dedicated controller for the manifest, which also had the advantage of not having to tweak the fingerprinted name and cache headers as the middleware in serviceworker-rails does.

Related

Turbo and Datatables initialization problem

I am using rails 6 to load a datatables with values. My sidebar looks like this:
<li class="nav-item" >
<%= link_to users_path, {class: 'nav-link', data: {turbo: true} } do %>
<i class="nav-icon icon-user " aria-hidden="true"></i>All Users
<% end %>
</li>
and my datatables is initialized with :
$(document).on('turbo:load', function() {
$('#users_data_table').DataTable( {
columnDefs: [
{
targets: 4,
className: 'text-center',
}
],
stateSave: true,
"order": [[3, 'desc']],
"pagingType": "full_numbers",
"dom": '<lf<t>ip>',
bProcessing: true
......
Examples with rails and Datatables are all over the place, eg: https://www.driftingruby.com/episodes/datatables
My problem:
When I click the link with data {turbo:true}, I get the following error:
DataTables warning: table id=users_data_table - Invalid JSON response.
If I disable turbo with data: {turbo:false}, datatable is initialized correctly.
Have you seen this before? Because it is driving me crazy. Why does turbo have to be disabled for this to work? I am totally baffled.

How to handle array response from elastic api with faraday?

I want to receive all Elastic Cloud configuration templates from the Elastic Cloud API with faraday in my Ruby on Rails application.
I've tried to workaround and modify the api call, but it's not possible to not get an array as a response.
This is the repsonse from the api:
[
{
"name": "Small Template",
"id": 1
},
{
"name": "Medium Template",
"id": 2
},
{
"name": "Big Template",
"id": 3
}
]
This is my faraday configuration.
Faraday.new(url: "https://#{ENV['ECE_USERNAME']}:#{ENV['ECE_PASSWORD']}##{ENV['ECE_HOST']}") do |c|
c.response :json, parser_options: {symbolize_names: true}
c.response :logger
c.use JSONParser
c.adapter Faraday.default_adapter
end
And the api call:
#conn.get('/api/v1/platform/configuration/templates/deployments?stack_version').body
This is the error message I receive
undefined method `has_key?' for #<Array:xxxxx>
I don't want to use anything else, but faraday. I'm open to new gems to help faraday, but this client should stay.
How can I setup faraday to handle the array response or how can I workaround my problem?

How to get webpack2 and underscore-template loader + babel to work without getting "Module build failed: SyntaxError: 'with' in strict mode (5:0)"

I have a underscore template loader in my webpack2 config that is transpiled with babel. It fails at compile time because with is used in the code compiled code. Here is the relevant part in my loaders in webpack.config.js:
I have this section under loaders:
{
test: /\.html$/,
use: [
{
loader: 'babel-loader',
query: {
presets: [
['es2015', { modules: false }],
'es2016',
'es2017',
'stage-3',
],
},
},
{
loader: 'ejs-loader',
},
],
};
This is what I want and I get:
ERROR in ./src/table/row.html
Module build failed: SyntaxError: 'with' in strict mode (5:0)
3 | var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
4 | function print() { __p += __j.call(arguments, '') }
> 5 | with (obj) {
| ^
6 |
7 | _.each(tableKeys, (k) => { ;
8 | __p += '\n <td>' +
If I remove the babel part completely it works but with ES6 code not transpiled:
{
test: /\.html$/,
use: [
{
loader: 'ejs-loader',
},
],
};
I have also seen this question about removing strict mode and have tried several things related to es2015 applying strict. I think I have tried every solution in that question including hotpatching workaround and I still get the same error. In the end i tried this:
{
test: /\.html$/,
use: [
{
loader: 'babel-loader',
query: {
presets: [
],
},
},
{
loader: 'ejs-loader',
},
],
};
I though this should do the same as without the bable pass, but I get the same error here. Somehow without any presets I get the same error.
EDIT
I have also tried to work around it by passing variable in query and I have made that work with ejs-loader, however I'm not looking for a solution where all the templates need changing.
I have made a repository which illustrates the problem. The master branch has babel-loader commented out and works with with while the transpile branch will have compile errors even though { modules: false } is passed and I have a branch called transpile-no-presets where all presets in package.json is removed and the error is still showing.
By default Underscore .template put your data in the scope using a with statement. See Underscore docs.
I think the cleanest solution is to instruct your ejs-loader to not compile to with statements but to use a temporary variable instead:
{
loader: 'ejs-loader?variable=data',
},
...and change your templates to reference the temporary variable.
From:
<ul>
<% _.each(test, (n) => { %>
<li>This is line number <%- n %></li>
<% }); %>
</ul>
to:
<ul>
<% _.each(data.test, (n) => { %>
<li>This is line number <%- n %></li>
<% }); %>
</ul>
Use version 1.0 of underscore-template-loader instead.

Fail to integrate CKeditor in rails_admin gem (use gem rich)

I follow the link GitHub gem rich to install CKeditor to rails_admin
but I get the error: Unsupported field datatype: rich_editor
My model
edit do
field :title
field :description, :rich_editor do
config({
:insert_many => true
})
end
field :autho
field :book_type
end
How can I fix this error? Or that's an issue?
EDIT:
I tried it, and it worked
field :content, :text do
ckeditor do true end
end
I couldn't get the Rich gem to work with a Rails 4 project using Rails admin, so I decided to use the standard CK Editor Gem which is the recommended course of action by the authors. It took all of 5 minutes to get it working following this:
https://github.com/sferik/rails_admin/wiki/CKEditor
Then I configured my CK_Editor to use a small subset of the available functionality.
After adding the CK_Editor gem and configuring my rails admin initializer, I created a new javascript file in my project at:
/app/assets/javascripts/ckeditor/config.js
with the following contents:
CKEDITOR.config.toolbar = [
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ],
items: [ 'Bold', 'Italic', 'Underline', 'Strike', '-', 'RemoveFormat' ] },
{ name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ],
items: [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote',
'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock' ] },
{ name: 'links', items: [ 'Link', 'Unlink' ] },
];
Remember to restart your Rails server!
I have the same issue. I think it is an issue in rails_admin or in rich. I have successfully integrate these two together in past (but with old versions of both).
I have created github issues for this in rich (https://github.com/bastiaanterhorst/rich/issues/80) and rails_admin (https://github.com/sferik/rails_admin/issues/1585) repos.

Ruby on Rails 3.1, Ckeditor custom toolbars. Where to place definitions

I used the gem to install ckeditor. As such there is no config.js in the project (there is in the actual gem folder that I don't want to modify). The install did create a ckeditor.js in the config/initializers folder that would seem to be the correct place to put the tool bar definition. But everything I have tried to get that to work throws a variety of syntax or method not found errors. Has anyone had success with this? If so a quick example would be very helpful.
My current ckeditor.js is:
# Use this hook to configure ckeditor
if Object.const_defined?("Ckeditor")
Ckeditor.setup do |config|
# ==> ORM configuration
# Load and configure the ORM. Supports :active_record (default), :mongo_mapper and
# :mongoid (bson_ext recommended) by default. Other ORMs may be
# available as additional gems.
require "ckeditor/orm/active_record"
# Allowed image file types for upload.
# Set to nil or [] (empty array) for all file types
# config.image_file_types = ["jpg", "jpeg", "png", "gif", "tiff"]
# Allowed attachment file types for upload.
# Set to nil or [] (empty array) for all file types
# config.attachment_file_types = ["doc", "docx", "xls", "odt", "ods", "pdf", "rar", "zip", "tar", "swf"]
end
end
1.Add following in application.js
//= require ckeditor/ckeditor
//= require_tree ./ckeditor
2.Add a config.js in app/assets/javascript/ckeditor
Sample config.js
if(typeof(CKEDITOR) != 'undefined')
{
CKEDITOR.editorConfig = function(config) {
config.uiColor = "#AADC6E";
config.toolbar = [
[ 'Bold', 'Italic', 'Underline', 'Strike' ],
[ 'NumberedList', 'BulletedList', 'HorizontalRule' ],
[ 'Blockquote' ],
[ 'Undo', 'Redo' ],
[ 'insertResolved' ],
[ 'Source' ]
];
}
} else{
console.log("ckeditor not loaded")
}
I have the same problem as yours. At first, I followed Config rails with asset pipeline but it doesn't work for me. Then I realized that the author of that link only create a new style of toolbar. You need to call it in the view also. That means you need to add this line
input_html => {:toolbar => 'MyToolbar'}
to make it works.
In order to test if the config.js is working, you can check the source of your webpage to see whether assets/javascripts/ckeditor/config.js is added.
Another way to check is to edit the editor color by uncommenting this line: config.uiColor = '#AADC6E'. If the color of the editor changes then it works.
I also made a stupid mistake that I include the ckeditor js files two times: once in the application.js, once in the layouts/application.html.haml file. Don't know whether this is the source of the problem or not. You can try.
Hope this helps.
this worked for me:
How to configure CKEditor in Rails 3.1 (gem + Asset Pipeline)
just save the snippet given in the answer, in config.js file
May be my comment on github will help you https://github.com/galetahub/ckeditor/issues/136#issuecomment-8870692
This is the updated answer to Rails 4.1 with ckeditor 4.1.0 to custom configure the ckeditor toolbar.
In your view, using simple_form, you need to config the input like this example:
_FORM.HTML.ERB
<%= simple_form_for(#foo) do |f| %>
<%= f.input :bar, as: :ckeditor %>
<%= f.button :submit %>
<% end %>
In your Javascript assets you need to create a folder called "ckeditor" and in there create a file called "config.js"
../JAVASCRIPTS/CKEDITOR/CONFIG.JS
CKEDITOR.editorConfig = function(config) {
//config.language = 'es'; //this could be any language
config.width = '725';
config.height = '600';
// Filebrowser routes
// The location of an external file browser, that should be launched when "Browse Server" button is pressed.
config.filebrowserBrowseUrl = "/ckeditor/attachment_files";
// The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Flash dialog.
config.filebrowserFlashBrowseUrl = "/ckeditor/attachment_files";
// The location of a script that handles file uploads in the Flash dialog.
config.filebrowserFlashUploadUrl = "/ckeditor/attachment_files";
// The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Link tab of Image dialog.
config.filebrowserImageBrowseLinkUrl = "/ckeditor/pictures";
// The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Image dialog.
config.filebrowserImageBrowseUrl = "/ckeditor/pictures";
// The location of a script that handles file uploads in the Image dialog.
config.filebrowserImageUploadUrl = "/ckeditor/pictures";
// The location of a script that handles file uploads.
config.filebrowserUploadUrl = "/ckeditor/attachment_files";
// You could delete or reorder any of this elements as you wish
config.toolbar_Menu = [
{ name: 'document', items: ['Source', '-', 'Save', 'NewPage', 'DocProps', 'Preview', 'Print', '-', 'Templates'] },
{ name: 'clipboard', items: ['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo'] },
{ name: 'editing', items: ['Find', 'Replace', '-', 'SelectAll', '-', 'SpellChecker', 'Scayt'] },
{ name: 'tools', items: ['Maximize', 'ShowBlocks', '-', 'About'] }, '/',
{ name: 'basicstyles', items: ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat'] },
{ name: 'paragraph', items: ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock', '-', 'BidiLtr', 'BidiRtl'] },
{ name: 'links', items: ['Link', 'Unlink', 'Anchor'] }, '/',
{ name: 'styles', items: ['Styles', 'Format', 'Font', 'FontSize'] },
{ name: 'colors', items: ['TextColor', 'BGColor'] },
{ name: 'insert', items: ['Image', 'Flash', 'Table', 'HorizontalRule', 'Smiley', 'SpecialChar', 'PageBreak'] }
];
config.toolbar = 'Menu';
return true;
};
The config for the application.js is like this, notice that the order of ckeditor and require_tree is important
APPLICATION.JS
//= require jquery
//= require jquery_ujs
//= require ckeditor/init
//= require_tree .
Now in your ckeditor.rb you should uncomment this line "config.asset_path" and add the path to the config.js file that you created before wich is "/assets/ckeditor/"
../CONFIG/INITIALIZERS/CKEDITOR.RB
# Use this hook to configure ckeditor
Ckeditor.setup do |config|
# ==> ORM configuration
# Load and configure the ORM. Supports :active_record (default), :mongo_mapper and
# :mongoid (bson_ext recommended) by default. Other ORMs may be
# available as additional gems.
require "ckeditor/orm/active_record"
# Customize ckeditor assets path
# By default: nil
config.asset_path = "/assets/ckeditor/"
end
I hope it helps :D!

Resources