How do I go about localizing data string that come from yaml files stored in the data folder
wondered if there were some techniques I have missed for this.
One way i am aware of, is using symbols (pointing to translation items) within your data:
/data/product.yml
title: :product_title
/config.rb
set :lang, :de
activate :i18n, :langs => [:de, :en]
These symbols can be translated as (Middleman) usual ...
/locales/de.yml
---
de:
product_title: "Mein deutscher Produktname"
/locales/en.yml
---
en:
product_title: "My english product title"
... and used in your templates:
/source/localizable/i18n.html.erb
<h1><%= I18n.t(data.product.title) %></h1>
http://0.0.0.0:4567/i18n.html
Mein deutscher Produktname
http://0.0.0.0:4567/en/i18n.html
My english product title
You can use .send method.
In /data/en/production.yml
---
title: "My english product title"
In /data/ja/production.yml
---
title: "私の日本語の商品名"
Then in your template...
<h1><%= I18n.t(data.send(I18n.locale.to_sym).product.title) %></h1>
Related
Currently users can download an ActiveStorage blob in my app using the following link:
link_to 'download', rails_blob_path(pj.document.file, disposition: 'attachment')
However, I would like to update an attribute in the database for the associated model to register when the file was first downloaded. This field is called the downloaded_at field.
I have made the following attempt:
Changed the link_to > button_to as I'm updating the model.
Added the appropriate route
Added the following code in the database:
def download
#proofreading_job = ProofreadingJob.find(params[:id])
#proofreading_job.update(downloaded_at: Time.current) if current_user == #proofreading_job.proofreader.user
response.headers["Content-Type"] = #proofreading_job.document.file.content_type
response.headers["Content-Disposition"] = "attachment; #{#proofreading_job.document.file.filename.parameters}"
#proofreading_job.document.file.download do |chunk|
response.stream.write(chunk)
end
ensure
response.stream.close
end
However, this does not do anything except redirect to the #proofreading_job page which is not what I want.
Has anyone done this before and if so how can I accomplish this task.
I think you can also try using your action controller as a proxy, the concept is this:
download the file in your action
check if it is downloaded successfully and other validations
perform clean up operations (in your case the added code in your #3)
send the file back to user using the send_data/send_file rendering method
E.g. in your controller:
def download
file = open(params[:uri])
validate!
cleanup!
send_file file.path
end
Then in your view:
link_to 'download', your_controller_path
Above is just concept and I apologize for only providing pseudo code in advance.
In the end I just used some javascript to capture the click of the button as follows:
td = link_to rails_blob_path(pj.document.file, disposition: 'attachment'),
id: pj.document.id,
download: pj.document.file_name,
class: "btn btn-outline-secondary btn-sm btn-download" do
=pj.document.file_name
i.fa.fa-download.ml-3 aria-hidden="true"
coffee script:
$('.btn-download').on 'click', (e) ->
id = $(this).attr('id')
$.ajax {url: Routes.document_path(id), type: 'PUT'}
routes.rb
resources :documents, only: [:show, :update]
documents_controller.rb:
def update
document = Document.find(params[:id])
authorize([:proofreaders, document])
document.update(downloaded_at: Time.current) if document.downloaded_at.nil?
head :ok
end
This seems to work very well. It updates the database and the user gets the file downloaded to their computer.
Summary
The Sonos self-test suite seems to incorrectly fail for an item with itemType=other if it also has a custom browse icon.
I believe that the item type other should be included in this list from utility.py:
17 BROWSEABLE_CONTAINER_TYPES = ('artist', 'album', 'genre', 'playlist', 'favorites', 'albumList', 'trackList', 'artistTrackList', 'container', 'favorite', 'collection', 'program', 'show')
Details
When running the sonos self-test suite, I got the following error as part of the output:
...
INFO Start Test Case: 844 Albumart test_custom_browse_icon_configuration
STOP Discovered custom browse icon URI should be something other than None. (is None)
STOP 844 Albumart test_custom_browse_icon_configuration
...
By debugging albumart.py (test_custom_browse_icon_configuration method), I traced the issue to the following extract of the get_sample_custom_browse_icon_url method:
# TODO: Need to drill down one level deeper if the target image url cannot be found on the root level containers
for mediaColl in response.Items:
if mediaColl.itemType in container_types:
if substitution_str in mediaColl.albumArtURI:
return mediaColl.albumArtURI
elif hasattr(mediaColl.albumArtURI,'value') and substitution_str in mediaColl.albumArtURI.value:
return mediaColl.albumArtURI.value
This code was supposed to find containers with custom album art. However, it turns out that container_types was defined by an earlier line:
container_types = [t for t in Validation.BROWSEABLE_CONTAINER_TYPES if t.lower() != 'album']
and Validation.BROWSEABLE_CONTAINER_TYPES was defined in utility.py as follows:
# sonos-selftest/smapi/content_workflow/utility.py
15 class Validation(WorkflowTestFixture, SMAPIClient, SMAPIService):
16
17 BROWSEABLE_CONTAINER_TYPES = ('artist', 'album', 'genre', 'playlist', 'favorites', 'albumList', 'trackList', 'artistTrackList', 'container', 'favorite', 'collection', 'program', 'show')
Note that the type 'other' is missing from this list! I'm pretty sure it is supposed to be inluded in the list, browse.py mentions it:
234 **Reference:** BROWSEABLE_CONTAINER_TYPES = 'artist', 'album', 'genre', 'playlist', 'favorites', 'albumList', 'trackList', 'artistTrackList', 'container', 'favorite', 'collection', 'other', ' program'
Workaround
I was able to work around this issue by changing itemType=other to itemType=container (which are pretty much equivalent).
However, it would be nice if this was fixed in future versions of the Sonos self-test suite.
Anyone have a way to pretty print JSON output from jbuilder?
I can pretty print JSON generated within a controller action with something like:
JSON.pretty_generate(some_json_object)
but once I pass off to a jbuilder template, I'm not aware of a way to have that output pretty printed.
Right now, my action method's render statement is simple:
render formats: :json
And this successfully forces a rendering with jbuilder, regardless of input format type specified (which is my desired behavior).
I found a way to do this:
json_string = render_to_string formats: :json
json_object = JSON.parse(json_string)
render :json => JSON.pretty_generate(json_object)
Again, this assumes there is a jbuilder template for this action, which will create the initial json, which gets rendered to a string, back into a json object and then passed to pretty_generate().
It's a bit circuitous, but it works. I'm of course, totally open to tighter implementations!
# config/initializers/jbuilder_prettify.rb
require "jbuilder"
class Jbuilder
##
# Allows you to set #prettify manually in your .jbuilder files.
# Example:
# json.prettify true
# json.prettify false
#
attr_accessor :prettify
alias_method :_original_target, :target!
##
# A shortcut to enabling prettify.
# Example:
# json.prettify!
#
def prettify!
#prettify = true
end
def target!
#prettify ? ::JSON.pretty_generate(#attributes) : _original_target
end
end
# app/views/api/v1/users/show.json.jbuilder
json.prettify! if %w(1 yes true).include?(params["pretty"])
json.( #user, :id, :name, :created_at, :updated_at )
https://github.com/rails/jbuilder/issues/195#issuecomment-44440569
Expanding on Blake Miller's answer...
Here is the code from the gist:
require 'multi_json'
MultiJson.use :yajl
unless Rails.env.production?
MultiJson.dump_options = {:pretty=>true}
end
I put this into a file called /config/initializers/jbuilder_prettify.rb
In order for this to work you must have the yajl-ruby gem included in your Gemfile. Note that the jbuilder github homepage mentions here how using something like yajl-ruby will speed up your json rendering.
This worked for me, while the accepted answer did not. It's also shorter!
https://gist.github.com/jmoe/02c7476adac24eddd969
require 'multi_json'
MultiJson.use :yajl
unless Rails.env.production?
MultiJson.dump_options = {:pretty=>true}
end
config/initializers/jbuilder.rb with:
class Jbuilder
def target!
::JSON.pretty_generate(#attributes)
end
end
Result, https://localhost:3000/manifest.json
{
"name": "Socializus",
"short_name": "Socializus",
"start_url": "http://localhost:3000",
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone",
"icons": [
{
"src": "/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
I think this is simpler,
#package = Package.first
json = JSON.parse(#blog.to_json)
PP.pp(json)
{"id_to_s"=>"5222675dbc11149e3a000002",
"title"=>"Package Title",
"version"=>"0.1.1",
"comment"=>
{"user"=>"Joe",
"description"=>"Joe's comment"},
"assets"=>
[{"id_to_s"=>"522a4620fa451436f4000001",
"_type"=>"Illustration",
"start"=>0,
"stop"=>100,
"caption"=>"mountain climbing"},
{"id_to_s"=>"522a56a6fa4514523a000001",
"_type"=>"Illustration",
"start"=>200,
"stop"=>300,
"caption"=>"airport"},
{"id_to_s"=>"522a6a0ffa4514a30e000002",
"_type"=>"Illustration",
"start"=>400,
"stop"=>600,
"caption"=>"doc"},
{"id_to_s"=>"522aa46bbc1114551f000001",
"_type"=>"Illustration",
"start"=>nil,
"stop"=>nil,
"caption"=>nil},
{"id_to_s"=>"522aa47fbc1114551f000002",
"_type"=>"Illustration",
"start"=>10,
"stop"=>30,
"caption"=>"asdflkjsd"}]}
Or, the quicker one-liner,
PP.pp JSON.parse Blog.first.to_json
Using rails 3.0.10, we need to send mail messages with html and plain text alternative where the html part references images sent along as inline attachments.
The code:
def invite(secure_share)
#share = secure_share
attachments.inline['download.png'] = File.read "#{Rails.root}/public/images/download.png"
mail( :to => secure_share.recipient,
:from => 'dummy#example.com',
) do |format|
format.html { render :layout => 'cargo_secureshare_mailer' }
format.text
end
end
The templates are in place, the inline attachment works and we get a mail with the following structure:
Content-type "multipart/related"
Part "multipart/alternative"
Part "text/html"
Part "text/plain"
Part "image/png" (inline attachment)
Neither Apple Mail nor Thunderbird seem to like this, they will not show the HTML version but only a text version with two "normal" attachments. It seems like the multipart structure is wrong - shouldn't it have "multipart/alternative" as the content type and then "multipart/related" as a wrapper for the html with inline attachments?
Anyone a hint how to fix this?
Found here: http://www.shortround.net/2011/04/07/multipart-alternative-multipart-related-email-with-actionmailer-for-rails-3/
It almost works. i.e. it works for regular attchments but fails for inlined
I've updated active_admin to version 0.3.0 to get internationalization working. But I have problems with it.
I have my pl.yml file updated with activeadmin section which looks like this:
pl:
active_admin:
blank_slate:
content: "Nie ma jeszcze rekordów."
link: "Nowy"
dashboard: "Dashboard2"
view: "Podgląd"
This didn't work, so I tried adding this code to my application.rb:
config.before_configuration do
I18n.locale = :pl
I18n.load_path += Dir[Rails.root.join('config', 'locales', '*', '.{rb,yml}')]
I18n.reload!
end
Now internationalization seems to work in development environment, but I still have problems in other environments. I have problem with dashboard: key. Normally, in short, when I18n doesn't find the key it puts key: with capital letter, in this example it would be "Dashboard". But in my case i have something like this:
Develoment:
Production:
Is there anyone who had the same problem? I'm I doing something wrong, or is this an activeadmin bug? Any solution?
I had the same problem. I needed to do this to be able to get it to work in both production and development:
config.before_configuration do
I18n.load_path += Dir[Rails.root.join('config', 'locales', '*.{rb,yml}').to_s]
I18n.locale = :nl
I18n.default_locale = :nl
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '*.{rb,yml}').to_s]
config.i18n.locale = :nl
# bypasses rails bug with i18n in production\
I18n.reload!
config.i18n.reload!
end
config.i18n.locale = :nl
config.i18n.default_locale = :nl
Not very pretty, but probably caused by a bug in Rails.
in application.rb
config.i18n.default_locale = :fr
I18n.locale = config.i18n.locale = config.i18n.default_locale
I18n.reload!
The key reason maybe caused by : Rails chose the locale from enduser's browser, but not your config file. e.g. a Japanese is visiting your website with his browser using English , then your Rails app will show him the "English" text, but not Japanese that you want it to show.
According to Rails i18n document: http://guides.rubyonrails.org/i18n.html, you have to first of all:
edit config/application.rb to set the default_locale
config.i18n.default_locale = :cn
edit your app/controllers/application_controller.rb, to add a before_filter
before_filter :set_locale
# for those user whose browser is not using our default_locale, e.g. a Chinese using English broser,
# just like me. :)
def set_locale
I18n.locale = params[:local] || I18n.default_locale
end
in this case, you should have the "cn" as the default locale.
check your view page, by adding these line of code to any of your page. e.g.
# in products/index.html.erb
<h1>Products List</h1>
default_locale is: <%= I18n.default_locale %> <br/>
current_locale is: <%= I18n.locale %>
the output result should look like:
Products List
default_locale is: cn
current_locale is: cn
and your Rails application should work as you expect.
An alternative that seems to work is creating an initializer with the following:
# config/initializers/i18n_reload.rb
Rails.configuration.after_initialize do
I18n.reload!
end