Best way to save localized static content - ruby-on-rails

I am creating an application to have administrators enter the a localized static content of a page.
For ex. nowadays the "About Us" content is English, I would like an admin to be able to enter the same "About Us" content in Russian.
How should I store the localized content?
I'm thinking that the admin won't be able to edit the YAML files for each language.
i thought storing all the data in a table and have a reference language id to it stored in a cookie.
Having a call to the locale cookie each time a view loads checking out which language I am using, comparing it to the database and then calling the specific row where language = en/ru/whatever.
any better way?

Nowadays, you can simply put index.fr.html.erb and index.en.html.erb in the same folder and rails will do the rest.

odin is right, I do mean storing multiple versions of pages in different languages,
I thought I could just leave it in YAML and in-place edit it and I stumbled across this -
http://asciicasts.com/episodes/256-i18n-backends
We change the i18n backend to Key-Value backend (Hash) but then it would mean that each restart of the webserver the hash will be lost and thus the article suggests using Redis another key-value storage which calls itself
Redis is an open source, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets.
It seems fairly clever saving it like this, because I still use the Rails l18n, meaning I can route everything fairly easily, but I am enabling the user to edit the content for each locale.

Related

Keeping users uploaded documents private

I believe this question is platform/technology independent, however I am using Ruby on Rails with the carrierwave gem.
Users upload documents to my site, and I need to keep them private. I am exploring the different options available to me, along with their advantages and disadvantages.
Option 1
Obfuscate urls to images to make them impossible to guess.
This would be relatively simple to implement and fast to serve up. However, if a url was made public by whatever means, security is lost.
Option 2
Have documents accessed through some sort of intermediate step that requires authentication. This would have improved security over option 1, but would place additional load on the server. A page containing previews of a number of uploaded documents would hammer the server.
Are there any other options available to me? Have I made any mistakes with my claims, or missed any important points?
I think the best option you have is to have a "key" for your documents. You can generate a key, with a certain lifetime, and when you go on /document/name/access_key, you find the record matching and return the file associated with the record. Never exposing the real URL.

How should I store scraped HTML in my webapp?

I'm a newbie to web development (and development in general) and I'm building out a rails app which scrapes data from a third party website. I'm using Nokogiri to parse for specific html elements that I'm interested in and these elements are stored in a database.
However, I'd like to save the html of the whole page I'm scraping as a back-up in case I change my mind on what type of information I want and in case the website removes the site (or updates it).
What's the best practice for storing the archived html?
Should I extract it as a string and put it in a database, write it to a log or text file, or what?
Edit:
I should have clarified a bit. I am crawling on the order of 10K websites a week and anticipate only needing to access the back-ups on once-off basis if I redefine the type of data I want.
So as an example, if was crawling UN data on country population data and originally was looking at age distributions but later realized I wanted to get the gender distributions as well, I'd want to go back to all my HTML archives and pull the data out. I don't anticipate this happening much (maybe 1-3 times a month) but when it does I'll want to retrieve it across 10K-100K listings. The task should only take a few hours to do around 10K records so I guess each website fetch should take at most a second. I don't need any versioning capability. Hope this clarifies.
I'm not sure what the "best practice" for this case is (it will vary by the specifics of your project), but as a starting point I'd suggest creating a model with a string field for the URL and a text field for the HTML itself, and save the pages there. You might add a uniqueness validator for the URL, to make sure you don't store the same HTML twice.
You could then optionally add model methods to initiate a nokogiri document from the HTML text, thus using the HTML string as the "master" record (in the DB) and generating the nokogiri document on the fly when needed. But again, as #dave-newton points out, a lot of this will depend on what you're going to do with this HTML.
I would strongly suggest saving it into a table in the same DB as the data you are scraping. Why change what works? Keep it all as you normally would, or write it all to a separate database entirely just in case and keep some form or ref to link the scraped data to the backups just in case.

Rails - Store unique data for each open tab/window

I have an application that has different data sets depending on which company the user has currently selected (dropdown box on sidebar currently used to set a session variable).
My client has expressed a desire to have the ability to work on multiple different data sets from a single browser simultaneously. Hence, sessions no longer cut it.
Googling seems to imply get or post data along with every request is the way, which was my first guess. Is there a better/easier/rails way to achieve this?
You have a few options here, but as you point out, the session system won't work for you since it is global across all instances of the same browser.
The standard approach is to add something to the URL that identifies the context in which to execute. This could be as simple as a prefix like /companyx/users instead of /users where you're fetching the company slug and using that as a scope. Generally you do this by having a controller base class that does this work for you, then inherit from that for all other controllers that will be affected the same way.
Another approach is to move the company identifying component from the URL to the host name. This is common amongst software-as-a-service providers because it makes sharding your application much easier. Instead of myapp.com/companyx/users you'd have companyx.myapp.com/users. This has the advantage of preserving the existing URL structure, and when you have large amounts of data, you can partition your app by customer into different databases without a lot of headache.
The answer you found with tagging all the URLs using a GET token or a POST field is not going to work very well. For one, it's messy, and secondly, a site with every link being a POST is very annoying to work with as it makes navigating with the back-button or forcing a reload troublesome. The reason it has seen use is because out of the box PHP and ASP do not have support routes, so people have had to make do.
You can create a temporary database table, or use a key-value database and store all data you need in it. The uniq key can be used as a window id. Furthermore, you have to add this window id to each link. So you can receive the corresponding data for each browser tab out of the database and store it in the session, object,...
If you have an object, lets say #data, you can store it in the database using Marshal.dump and get it back with Marshal.load.

Storing formatted text in Resource File .Is it Possible?

Building an asp.net mvc website that has to be multilingual and wondering if it's possible to store formatted text in a resource file and whether it makes sense.
Lots of pages are static and user can edit them and add their own formatting "Bold,italics etc.."
and was wondering what is the best way to approach it.
I dont want to create one page x language and storing in the database involves creating a structure to handle the same info in multiple languages.Seems hard to maintain.
Have you done it before? How did you do it
any suggestions
Thanks a lot
Is it possible?
Certainly.
Does it make sense?
It depends. I would not recommend resource files (via ResourceWriter) for storing dynamic content.
Your problem
Let me rephrase it (I am not sure if I understood you correctly). You want to give your users an ability to change presentation style. User will be able to change the style and that change would be somehow propagated to whatever languages the content is translated to.
In such case, I see some issues:
How to match English contents with translated one?
It is typical for translation to have different order and possibly different number of sentences. There is no way to match them unless...
Storing such information in resource files along with translatable strings would result in something that is hard to maintain. I believe you would need to either add formatting tags or content tags with styling information in order to achieve that. The result would be a mess; hardly readable, as tough to modify.
OK, so what can you do? Actually, what I could recommend is to create Customization Mechanism for CSS files. In your case you need:
Provide CSS classes as well as unique identifiers (HTML id attribute) to each structural elements (tags if you prefer), so that you have something like <div id="main" class="main"><p id="p1" class="normal">.... The id's will give users an ability to target precisely that element leaving others untouched (via #p1.normal { // definition here }).
Store CSS in the Database and create some editor for users.
Create a Handler to serve CSS from database upon web browser's request.
Even with such solution you won't avoid some problems. One is that you need to actually alter font family while translating into certain languages, so you might need language-based CSS files. Another problem pops up when user wants to put bold attribute on certain word - with such solution this is not possible (but to be honest if you want to allow that, this won't be i18n friendly for the reasons I mentioned earlier).
BTW. Bold fonts should be avoided for some languages. For example Chinese characters are pretty hard to read if you manage to output them with bold font.
If your users can post in multiple languages - its probably best to use a database to store the info and accompanying formatting. If it is for labels and other static text on the website - the resource files are a good solution. The resource files store the content as strings - but storing formatted text in there breaks the 'seperate the presentation from the logic' idealogy.

Accessing Word documents in a Rails app

I have a number of documents (mainly Word and Excel) that I'd like to make available to users of my Rails app. However, I've never tried something like this before and was wondering what the best way to do this was? Seeing as there will only be a small number of Word documents, and all will be uploaded by me, do I just store them somewhere in my Rails app (i.e. public/docs or similar) or should I set up a separate FTP and link to that? Perhaps there's an even better way of doing this?
If they're to be publically accessable, you definitely just want to stick them in public somewhere. Write a little helper to generate the URL for you based on however you want to refer to them in your app, for cleanliness (and so if you do change the URL later, for example to bucket your files to keep your directory sizes under control, you don't have to change links all over your app, just in one place.
If, on the other hand, your files are only for logged-in users, you'll need to use something like send_file to do the job, or one of the webserver-specific methods like the X-Sendfile header to check the user is authorised to view the file before sending it back to them.
I would do as you suggested and put them in public/docs. If you are planning on making an overview/index page for the files and link directly to them it would be easier if they were stored locally instead of a remote FTP server. However, since you are the one who will be uploading and maintaining these files, I think you should go with the option that's easiest for you.

Resources