End user can edit the view of a recored in some sort of editor - rails - ruby-on-rails

I'm looking for something like an editor but instead of the user editing just a post or page the user can edit the default template layout or view layout for all pages associated to something.
I'll give an example to get my question across because i really don't know what it would be called.
Say for example you have categories. (people, animals, etc..)
Now imagine there is a category of people, each person in the category has the keys 'height', 'weight' and 'age' and each key has values assigned to them (height: 120 cm, weight: 80 pounds, age: 25)
I want the user to be able to edit the layout of the people page (page template or view that each person is displayed on) and be able to add in the keys they want to be displayed on the page.
So say they add the keys ‘height’ and ‘weight’ it will only display the height and weight on every person page, plus whatever pre set text the user added in the template editor for the people pages to display.
I could probably find a good editor that can be customised and change it to my liking but there might already be gems out there made for this.
My question is, is there a gem for basically letting users set templates for record pages.
Even if there is something out there to change views for objects but the user cant set the keys on it, i'd still like to see it because I might be able to add the key/value functionality to it.
Hopefully you understand what I'm looking for.
UPDATE
Ok so i appears I'm after an editor that works with a template engine like liquid or one thats both an editor and template engine.

If you plan on building from scratch, it sounds like it could be done using rails generate scaffold this allows views/models/controllers to create pages for each of your categories.
Then you can use Associations to create associations between your categories.
You can also make different user roles by making a field called "Role" in your Users relation
Otherwise, there are also open-source software Active Admin to manage content for your categories.
EDIT: After looking around I found a gem you can use to have end-users edit your own views, feel free to check out Liquid.

Related

Rails question: What's the optimal way to create user customisable UI texts

I have a regular rails app with index, show pages, and forms.
I'd like to allow the administrators of the site to customise the default texts across the site without code changes.
For example, the admins should be able to change a page's H1 tag from "User Index" to "Customer Index", or change a form label from "User Name" to "Customer Name".
I was thinking to create a model called ui_texts that has two fields:
machine_name: string
value: string
Then, I would replace the current hard coded texts with a query like:
Ui_text.where(machine_name:"user_name").value
The admins would have a simple CRUD to edit the ui_texts from the admin interface.
The problem with this approach is that a complex form will generate dozens or even hundreds of database queries to populate all the UI texts.
Even if I index by machine_name, the extra queries will add considerable time to the page load.
I wonder what is the optimal way to achieve such functionality?
You can use i18n to localize your application and set it up to use a database backend. Expect this to take a few hours of your time, it's rather cumbersome.
https://guides.rubyonrails.org/i18n.html
https://guides.rubyonrails.org/i18n.html#using-different-backends
After you set this up it will be trivial to create a CRUD section in your application where users can edit whatever messages they like.

Editable blocks on page (not related to model - related to SEO) in Ruby on Rails

My SEO-people do not write code. All they love is creating good texts. All they can do is pasting texts do database via some nice forms.
The problem is that sometimes they ask me: we need to put the text into page footer. Wee need to put some other text into page header.
And I just can not edit the code every time SEO-man asks me!
And sometimes the text are not related directly to model. I think you will understand me that it is a bad idea to create footer_block field inside a Car or Person model.
How nice it would if there was a gem that could:
Load text data from database by key (for example 'FOOTER_BLOCK'). To let me not to turn the models into a mess!
Give us forms where a SEO-person could paste the text
(Would be nice) Give us a WISIWIG editor.
PS: An example of such functionality (but not in Ruby): I used to code in python/Django. And we used django-flatblocks package - it did fit these 3 criterias.
I don't know any gem which will do this, but hopefully I can shed some light on how you might be able to achieve it
Code Blocks
You could create a table (and model) called code_blocks. The schema may look like this:
code_blocks
id | title | body | created_at | updated_at
This will allow you to create any number of records in this table that you want, and then call them from your app without the need for specific controller actions
Display
You could do this:
#app/helpers/application_helper.rb
def code_block(id)
block = CodeBlock.find(id)
return block.body
end
This may be inefficient, but it will allow you to include the code blocks whereever you want on the page, independent of the controller actions
So, for example, you have a footer block with id as 3, you could put:
<%= code_block(3) %>
Editing
This will mean that if you have a simple backend form, you can set it up so that you list the blocks by title, and allow the SEO guys to edit the HTML with a WYSIWYG editor (saving the HTML in the body column)

How to tag data from one model to a separate controller in ROR?

Problem:
I am trying to create an app whereby a person can 'click' on tag buttons that are of different sports preferences (ie: "Running", "Involves Bats"), each of which are tagged to certain sports. So, if the user selects the tag "Involves Bats", then the app will generate all associated sports such as "Baseball", which would have "Involves Bats" as a pre built tag.
What I've Done So Far:
I have added the acts_as_taggable gem
I have created a model for "Sports", that has no controller.
I have in seeds.rb created defined the "Sports" model with names of each sport.
I have a Users controller, where someone can submit email which takes to them to the their user page.
What is Left
I need to tag all preferences (ie "Running") to all potential "Sports". I am having a really difficult time doing this.
I also need to on the Users Page, show the tags ("Running") from which to choose.
I need to let User select the tags, and then generate the recommendations of Sports based on the associated tags
I know this is a fairly complex question, but I believe is a fairly common/basic app to build.
Thanks!
You should check out Railscast episode #382 on tagging: it shows exactly what you need!
http://railscasts.com/episodes/382-tagging

How to create a tagging system like on Stack Overflow or Quora

I want to create a tagging system like seen here on Stack Overflow or on Quora. It'll be its own model, and I'm planning on using this autocomplete plugin to help users find tags. I have a couple of questions:
I want tags to be entirely user-generated. If a user inputs a new tag by typing it and pressing an "Add" button, then that tag is added to the db, but if a user types in an existing tag, then it uses that one. I'm thinking of using code like this:
def create
#video.tags = find_or_create_by_name(#video.tags.name)
end
Am I on the right track?
I'd like to implement something like on Stack Overflow or Quora such that when you click a tag from the suggested list or click an "Add" button, that tag gets added right above the text field with ajax. How would I go about implementing something like that?
I know this is kind of an open-ended question. I'm not really looking for the exact code as much as a general nudge in the right direction. Of course, code examples wouldn't hurt :)
Note I am NOT asking for help on how to set up the jQuery autocomplete plugin... I know how to do that. Rather, it seems like I'll have to modify the code in the plugin so that instead of the tags being added inside the text field, they are added above the text field. I'd appreciate any direction with this.
mbleigh's acts_as_taggable_on gem is a feature-complete solution that you should definitely look into a little more closely. The implementation is rock-solid and flexible to use. However, it is mostly concerned with attaching tags to objects, retrieving tags on objects, and searching for tagged items. This is all backend server stuff.
Most of the functionality you are looking to change (based on your comments) is actually related more to your front-end UI implementation, and the gem doesn't really do much for you there. I'll take your requests one-by-one.
If user inputs a new tag, that tag
gets added, if user inputs an
existing tag, the existing tag gets
used. acts_as_taggable_on does this.
Click a tag from suggested list to
add that tag. This is an
implementation issue - on the
back-end you'll need to collect the
suggested list of tags, then display
those in your presentation as links
to your processing function.
Autocomplete as user enters
potential tag. You'll use the jQuery
autocomplete plugin against a list
of items pulled off the tags table.
With additional jQuery, you can
capture when they've selected one of
the options, or completed entering
their new tag, and then call the
processing function.
Restrict users to entering only one
tag. This will be your UI
implementation - once they've
entered or selected a tag, you
process it. If they enter two words
separated by a comma, then before or
during processing you have to either
treat it as one tag, or take only
the text up to the first comma and
discard the rest.
When you process the addition of a
tag, you will have to do two things.
First, you'll need to handle the UI
display changes to reflect that a
tag has been entered/chosen. This
includes placing the tag in the
"seleted" area, removing it from the
"available" display, updating any
counters, etc. Second, you'll need
to send a request to the server to
actually add the tag to the object
and persist that fact to the
database (where the taggable gem will take over for you). You can either do this via
an individual AJAX request per tag,
or you can handle it when you submit
the form. If the latter, you'll need
a var to keep the running list of
tags that have been added/removed
and you'll need code to handle
adding/removing values to that var.
For an example of saving tags while editing but not sending to server/db until saving a form, you might take a look at the tagging functionality on Tumblr's new post page. You can add/remove tags at will while creating the post, but none of it goes to the database until you click save.
As you can see, most of this is on you to determine and code, but has very little to do with the backend part. The gem will take care of that for you quite nicely.
I hope this helps get you moving in the right direction.
The more I try to force the acts-as-taggable-on gem to work the more I think these are fundamentally different types of problems. Specifically because of aliases. The gem considers each tag to be its own special snowflake, making it difficult to create synonyms. In some cases it doesn't go far enough, if you want the Tag to have a description you'd need to edit the given migrations (which isn't hard to do).
Here's what I'm considering implementing, given the trouble I've had implementing via the gem. Let's assume you want to create a tagging system for Technologies.
Consider the following psuedo code, I haven't yet tested it.
rails g model Tech usage_count::integer description:text icon_url:string etc. Run the migration. Note the
Now in the controller you will need to increment usage_count each time something happens, the user submits a new question tagged with given text.
rails g model Name::Tech belongs_to:Tech name:string
Name::Tech model
belongs_to :tech
end
Then you could search via something like:
search = Name::Tech.where("name LIKE :prefix", prefix: "word_start%")
.joins(:tech)
.order(usage_count: desc)
.limit(5)
This is starting point. It's fundamentally different from the gem, as each tag is just a string on its own, but references a richer data table on the back end. I'll work on implementing and come back to update with a better solution.

How to structure content in Ruby (RoR) app?

I am in the process of building a super simple CMS to handle smaller "static" page type projects (e.g. - small sites for friends). I have different "page types" that I would like to add. I built something similar in Coldfusion previously. Looked something like this:
table content_type:
content_type_code varchar(10)
content_type_name
table content:
content_id
content_type_code varchar(10)
content_name
content_desc
content_url
I would create a content type called "blog" or "photo" and each time a content was added, it'd get assigned the content_type_code. Then in /blog/ I'd query for all content that had a content_type_code of "blog".
Now that I'm using Ruby/RoR I am trying to think about things differently. I was thinking a better way might be to use nested pages with awesome_nested_set (https://github.com/collectiveidea/awesome_nested_set). But I'm not sure if that's the best solution.
Then I could create a page called "blog" and add to that many pages. So essentially the top level would take place of the "content_type" from my previous example.
Can someone steer me in the right direction on what the best method would be? I'm a newb looking for a kick in the right direction.
EDIT
I should add that the only real thing that I would change between the different "types" of content would be the layout and where they are displayed ("photo" content at /photos/, "blog" content at /blog/).
I try to recap:
You want to build a CMS
Your CMS manages a single web site
A web site is made of content
There are differenti type of contents, and I am assuming every type of content has its own behaviour
Contents are organized in a tree
Here is the plan I suggest you:
Create the Content resource; use the scaffold to have something already working, adding few field (title and body in example)
Add validations to your new model
Write a couple of unit tests against your validation (quite useless, just to see how it works)
Install awesome_nested_set and manage to make it working with your model
Work on the UI to make it quite easy to create new content, move content around, edit a single content
Now its time to implement the content types; STI is the Rails way, but I have to warn you it can be really hard. I suggest you to reiterate 1, 2, 3, 5 to create new models for Photo and BlogPost
Once you will be there, you will have hundreds of ideas to implement. Have fun :)
Instead of using content_type I would rather let the user choose a model on a selection page, like "photo" or "blog" and load an editing page based on that selection. So the user wants a new 'blog'-entry they get redirected to blog/new or 'photo' for photo/new. It's the easiest way to go in terms of usability and your controlling backend and you don't have redundant data (for example an empty photo url which is not necessary in a blog-type) in your database.

Resources