Letting users write DB-stored CSS for custom layouts - ruby-on-rails

I'm currently building a web app (atop Ruby on Rails), which will let users style their own areas (personal blog pages), and was wondering what are the best ways of accomplishing this?
I think Liquid for templating would be good, but how would you handle styling? My aim was to have a DB field associated with each blog dubbed "style" which will store a custom stylesheet, is this the best approach?
I've tried it so far with the "sanitize_css" helper method, but it just strips the "#stylebox" tags out, meaning nothing is displayed.
Any ideas?
Thanks.

Currently I'm also working on almost a similar requirement as you do. I'm also trying to create a CMS for users to add pages, style them etc..
My Approach as follows
each user will have his/her subdomain. (I use a before_filter to get the current users subdomain and load his/her website)
About styling, I prefer to have the style sheet as a physical file. Given that your method will have the more flexibility of editing the style sheet, I dont like the idea of having the stlesheet code on top of my page. Insted, I allow users to load their styleshets (Using paper clip)
So when the site loads I will get the css paths from the DB and load the stylesheet from the path.
Later I'm planning to read the file and load it to a textarea so that users can edit their stylesheets and when saving override the existing file;
For layouts i use liquid as well
cheers
sameera

I would honestly allow themable elements on your page, and then store each of those style rules as a field (or conglomerate them into one giant field) in the database. Enforce some validation to ensure that they don't use any funny business (if they're only coding for specific div's, they shouldn't need to use any curly braces.)
Then generate the CSS on the fly.
The reason? If you ever want to serve up ad's on your site, and you allow them to just upload the entirety of their CSS, they can easily turn off visibility on the ad div.
I think it's "safer" to control what they're allowed to theme; sure more advanced users will get ticked. But do you really want to be the next MySpace? ;-)

if there is too much of code then serialize the data and store it as text in db.
That would be much better i think

If your going to allow areas for users to have complete control over their CSS, then I would probably avoid the database altogether and use a structured file system approach. You could create a sub-domain or folder for each user that contains a main.css. This also allows you to scale well as features grow for your user (pictures, etc.)
With that said, as Robbie mentioned, you might want to consider limiting what styles a user can and can not control. Otherwise, you would probably find things getting out of hand quickly. For this approach, you would probably want to use the database for storing property values of the elements that can be modified.

Related

Multisite application in Rails (like shopify.com)

I would like create web app like shopify.com.
User can pickup subdomain(or domain), theme and have own store.
How can I do this?
Create main application, deploy it automatically like new standalone version and update it via git?
I'm using Rails 3.
Thanks for your advice.
Based on replies:
When I choose to use only one application (without multiple instances) and give user his subdomain, it will looks like their own website. But everything will be in one database (It's good idea?). And how can I have multiple themes in Rails app?
Take a look at LocomotiveCMS, specifically the routing system. Locomotive actually hosts multiple sites inside a single rails application. It does this by inspecting the request URL when it comes in and setting the current_site variable with the site which is set up to handle the domain. Then the current_site is actually just an object which contains all the pages, contents, settings, etc. for the specific site being served up.
So to answer your question, I think a good solution is to give your rails app the ability to serve up multiple sites based on the domain. It's not that hard, and it seems less fragile to me than trying to automatically deploy new instances of an app.
So far I have understood, you want to let your users have their own subdomain, different theme but the functionality would be same right. Users just need to have a feel of something of their own.
Well definitely, you need to have a single application that supports multiple subdomains.
A quick googling gave me [ http://37signals.com/svn/posts/1512-how-to-do-basecamp-style-subdomains-in-rails ]. May be you can get some insights from here.
For example if your service is http://www.myfi.com, a brief idea can be:
When a customer is registering, you should let him choose his subdomain. And the newly created account will be associated with this subdomain with a url. Say, http://customer1.myfi.com.
You should register for domain *.myfi.com so that anyone in the world hit with anysubdomain.myfi.com, it comes in your application.
Then from the url part, you should identify the subdomain (customer1) that is being used, and need to set that in session.
Now when someone will try to login, you must verify the account in the context of that subdomain's account.
In fact, all following actions need to be handled in the context of the subdomain's account.
Just tried the gather a glimpse of the implementation here. If you have confusion about something specific, share that also.
Edit:
Whenever you are thinking about multiple theme, you must have simple design which is completely driven by css and js. The app/view files should contain only content and HTML nodes with class names or ids.
Generally a UI designer can put more helpful ideas about how to make such theming mechanism. But all I can feel is, based on the chosen theme by customer, you have to load different css and js.
Actually the strategies can be indefinitely sophisticated and scalable, but its always wise to start with something easy. Then ideas will automatically evolve into better ones.

Rails Active_Admin VS. my own backend

I've been thinking of writing my own backend, because I feel active_admin might not support all the requirements.
I wanted to ask if Active_Admin supports any of these just to be sure:
I have a has_and_belongs_to_many relationship between my ad model
and tag model. In the new ad page I would like to have the form for
the ads, as well as all available tags so the admin can choose which
tags to associate with the ad. I was able to do that normally in my
application, but can I do that with active_admin?
Can I add custom buttons.. Like one to convert to PDF for example,
or one to send an e-mail..
Could I add some sort of before_filter, so the admin can only view a
model, but not edit or delete it for example?
Thank you.
All of those things can be done via Active Admin, but as it was pointed out, it can be quite a nightmare actually implementing certain things depending on the amount of flexibility you need it to have. For that exact reason, I decided to start rolling my own administration panels.
I have tried an implemented almost all robust gems for admin panels. I have also sweated over several hand-made ones.
Active-Admin is very usability centred, but it is not configuration centred.
As you rightly aniticipated, some of the more complex modifications can be tedious.
In my experience, rails_admin is the best middle ground I could find.
Take a look at it, it is highly functional, completely modular (made as a Rails 3 Engine) and simpler to modify.
If you can live without some details when customizing this is definitely the way to go. However, if you need to have everything just right, then there is not substitute for hand-made.

Rails Giving Each User Their Own Customizable Stylesheet

This is a fairly straightforward question.
I have Users in my Rails3 Application. I want to give each user the ability to customize their stylesheet through a form so they can essentially have their own themes.
I was wondering how I can go about getting this to happen and what is the best way that you have seen it done?
Would I need to use LessCss and if so, can I pass variables from a controller to the lesscss sylesheet?
Despite that sounding like a terrible idea I guess an easy way to do it would be to add a CSS table and map it to the user with a record for each CSS file. When a new user is created you create new records for each file using the default CSS.
To edit you could present the user with the CSS text on a page with some sample mini-page where they could see the changes happen live. You would then need to load the CSS dynamically which could be a huge hit on your database so you'd want to add some memory to the call to retrieve the CSS.
Again though, this is a horrible idea in my opinion. What happens when the user messes up and then can't use the site because they put in some bad value? They can't change it back because they can't see anything so what do they do? They never come back.
You'd be better off just allowing them to pick from a set of allowed themes. But hey, it's your website, you do with it as you please.

Ruby on Rails: CSS and skins management

I have a skin support in my app. I'm looking for a tool, which will enable the customer (not the programmer, which is current) alter the skins.
Is there an admin tool (gem, plugin) for Rails to manage (edit, create, view) these skins? I looking for some easy solution like /admin/skins page where I could do all the stuff, otherwise I'm going to write my own one.
In case there's no such tool - is there any best practice example (possible from other language/framework)? What kind of approach is used in other languages/frameworks?
Any kind of help is appreciated.
Is the theme_support gem a possible solution?
This actually depends on what you want styled. I'm not sure if there are any plugins out there that I haven't heard of yet, but personally I'd just do my own skin styler if I was in your shoes.
My idea is either give your users the ability to customize their page entirely ala myspace in which case you just have to create a semantically robust HTML then make a css uploader that will use their css files for the design.
Or you could limit your users to what you want styled so you can still maintain the basic layout of your site. Just give them access to coloring their fonts, resizing or coloring their backgrounds. No floats or whatsoever. In this case, you have to create something that will take a color/font-size as an input and change that depending on what the user picked.

Security in a Rails app - User submitted data

I'm currently in the process of writing my first Rails app. I'm writing a simple blog app that will allow users to comment on posts. I'm pretty new to Rails, so I'm looking for a bit of guidance on how to address security concerns with user input.
On the front end, I am using TinyMCE to accept user input. It is my understanding that TinyMCE will strip out any suspicious tags (e.g. <script>) from user input before posting to server. It seems that this could be bypassed by disabling javascript on the page, allowing a user to have free reign in the text area. TinyMCE recommends using javascript to create the TextArea. Therefore if the user disables javascript, there will be no text area. Is this the standard solution? It seems like a bit of a hack.
On the back end, what is the best way to strip out malicious code? Would I want to put some sort of validation in the create and update methods inside my comments controller? Is there some functionality built into Rails that can assist with this?
When displaying the information back out to the user, I'm assuming that I don't want to escape the HTML markup (with <%= h *text*%>), because that's how its stored in the back end. Is this bad practice?
I'm generally a big fan of cleaning out the data prior popping that stuff into the database. This is a debatable practice, but I usually lean toward this.
I use a modified version of the old white_list plugin to not strip out the html, but to convert anything I do want into a safer format.
<tag>
becomes
<tag>
This way I'm not really altering the content of the submission.
There are some plugins that specifically handle sanitization using a white/black list model.
http://github.com/rgrove/sanitize/ # Have not used, but looks very interesting
http://github.com/imanel/white_list_model # Used, not bad
There is also act_as_sanitized, but I have no real info on that.
And of course using the h().
Your suspicions are justified, but the creation of a text area in javascript won't make you any less vulnerable. A user could always use something like curl to force a form submission without ever visiting your site through a web browser.
You should assume that a user can post malicious scripts into the comments, and escape it on the frontend. Using <%= h(...) %> is one way to do it, or you can use the sanitize method in the same way. It will strip any scripts and escape all other html except for a few common tags that aren't harmful. Documentation for sanitize.
In addition to nowk's suggestions there is also the xss_terminate plugin. I have been using it in some of my applications. I found it to be easy to use, it needs almost no configuration, and has been working like a charm.

Resources