Reputation: 2017
I have a complicated questions that I've been stressing my head with for the last few days. I'm wondering what would be the best code arcitecture approach in resolving the following issue:
I have a web app that creates widgets. Each widget can have its own template (theme) - there are multiple templates that user can choose between. User can customize specific parameters for each widget template such as color, text, size, etc..
Each template has its own fields (with default settings), html template file and stylesheet.
What would be the best approach in Rails app, so that it would be transparent, logical organization, easy to change and create new templates? I would like to keep it simple and modular.
We don't plan to change templates often, so its okay if they are hardcoded.
I was thinking of 2 options: 1. create a model Template, which defines fields with default settings (serialized text), view template and stylesheet 2. create a model, which would point to a Template specific class, that would derive from the parent Template file.. this would give much more flexibility
The template should return stylesheet and template view with inserted configured values.
I would really appreciate if someone could point me to some good practices that I could use, and not reinvent the wheel and make it too complicated or useless. Any feedback is highly appreciated.
Thanks a lot!
Upvotes: 1
Views: 475
Reputation: 326
I believe an architecture like this one satisfies all of the requirements you specified above.
First, you have your two "core" models and their (very basic, haha) fields:
User
:id
:name
Widget
id
name
Next, you have the ThemeTemplate
model, which belongs_to
Widget
and is responsible for storing the default attribute values along with your CSS and HTML code templates:
ThemeTemplate
id
widget_id
name
attributes
, which stores a simple JSON hash of your attribute key/value pairs; for example: {width:50, height:100}
css_code_template
html_code_template
The css_code_template
and html_code_template
field should contain easily replaceable attribute key markers. For example, {{width}}
and {{height}}
.
Now, you need a way to bind the Widget
to the User
before we tackle our last model.
UserWidget
id
user_id
widget_id
theme_id
, which stores the ID of the currently selected Theme
(see below)generated_css_code
*generated_html_code
*
These two are optional in case you don't want to keep calling the generate_css_code
and generate_html_code
methods of Theme
.
Last but not least, we have the model that stores all the custom attribute values.
Theme
id
name
user_widget_id
theme_template_id
custom_attributes
, which stores a simple JSON hash of attribute key/value pairs; for example: {width:55, height:105}
This model should also have the generate_css_code
and generate_html_code
methods, which should read the code from the css_code_template
and html_code_template
of ThemeTemplate
and replace the attribute key markers with their custom (from Theme
) or default (from ThemeTemplate
) values.
The problem with custom templates is you always want to make sure you have plenty of error detection in place.
Needless to say, the example I described above is a very simple way of tackling your requirements. One enhancement could be using a "NoSQL" database (such as MongoDB) for storing your attributes.
Upvotes: 2