How to Use the Rails Content Tag Helper to Auto Generate HTML Code
So far we've covered the ability to hard code HTML code into a Rails view helper method. In this guide we'll walk through how to leverage the content_tag helper method to auto generate HTML code in a Rails 5 application.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

Looking at our pivotal tracker dashboard, we can see that we've actually already covered one of these items. Partials with local variables. So I'm going to cross that off the list and then I was thinking about adding one new guide that was very cool, which is to talk about some view helper methods. I was going to include that in the deep dive but then I started to think about it and I realized that there were some methods that we could use in our own application. I think that would be a good one to swap out since we already are a little bit ahead of track because we took care of this one. So that's enough on the project management side.

Let's actually get into the next item on the agenda which is integrating content helpers. So what is a content helper? We have talked about all kinds of things with views we've talked about partials we've talked about things like creating helper methods all of these kinds of things. A content helper fits kind of in-between those items. Content helper methods are items that we can use and the processes we can use inside of either our views or even inside these types of methods.

Let's go with a base case scenario. I'm going to open up home. Let's talk about how this could be implemented. What I'm going to show you isn't going to make the most sense because it's the base case. I'm going to show you where it really comes into play right after this.

So you use some embedded Ruby and I'm going to say content tag and pass in some values. Here I can just say :p for paragraph and then I can also pass a class. For this class, I can say something like "my-special-class" and then give it a block and do that. Then we have to tell rails when the content has ended and now inside of this I can put anything I want. So here I can say "Hi, I'm in a paragraph tag" and hit save.

large

Now let's start up the rails server and see what this has for us on the homepage. Coming to the site press home you can see that says "Hi I'm in the paragraph tag" and if I click on this and click inspect. This is going to bring up the inspector tools. And as you can see it generated all of this HTML automatically for us. It created a p tag, It put our content inside of it and it even added our class. So that's pretty cool. That's a nice way of being able to dynamically generate HTML and then be able to show that on the page. So that's neat. It's good to know, however, it is pretty rare that you're going to use this because what's the point of using this when you could implement the exact same thing just by saying <p class="my-special-class">Hi, I'm in a paragraph tag</p>

Now we also can give other content tag items so we could say H1 and now say "I'm in a heading" save and come back, you can see that gave us a heading and it generated H1 content for us. All of that's good. Still, this isn't exactly the best use case where this comes in incredibly handy is actually in our helper methods.

When we create a new_helper, you can see we have the ability to pass in direct Ruby. What happens when we do something like this, we say def sample_helper like we did before. Remember how we had to pass in or in hard code our tags like this. I put some content in there, then afterward in order to make this actually functional we had to say .html_safe. That's really not a good experience. This is not the type of code you'd want to write. That is where our content tag Helper comes in so handy. What we can do and we'll test this exact one out right here, I'm going to delete all of this in our sample helper and let's create just a very basic one. I'll say content tag and this time I'm going to pass in a div, this is going to create a div for us and then inside of the next argument I'll say "my content" and then we can also pass a class, "my-class". Now we can call this sample_helper method right here.

large

If I come back you can see it has my content, if I inspect the elements you will see that this is in a div and it has a class of my class that was added. So that is very neat. Now, this is starting to actually make sense on why that you'd want to use a content tag because look at how much cleaner this is. It is also much more dynamic, it's easier to slide in and change. What happens if you want to change the class based off of the type of user that's logged in. A good example would be say that you have a header or something like that and you want a different type of set of styles for your admin users compared with guest users. Then you could slide in dynamically based off of the user type and give different class names and all of it's happening here in the view helper instead of in the actual view itself. I'm going to get rid of our test line (delete <%= sample_helper %>)

and let's talk about actually building a real one something that we can actually use. Let's open up our trusty layout files

  • application.html.erb
  • blog.html.erb
  • portfolio.html.erb

Hopefully, by going through all of this and all these refactors this is showing you how important these kinds of mechanisms are and emphasizes how critical it is to utilize these kinds of tools so that you can be as efficient as possible.

I want to refactor our little session source tracking system. I'm going to get rid of this and come into the application_helper.rb and I will say Source helper. We don't have to call these methods helper, I simply like doing it just because it's very clear when I'm looking at the methods that I know automatically that that's a helper method. I'm going to say if session source because we do have access to that so we can put this conditional inside of this source helper method and I can come here and get rid of all of this stuff. I can convert all of this into a string. Then I can pass this session source because this is something this is actual ruby code. Remember this is our look up and it finds a session and if a source is provided then it's stored in the session and this is what is printed out. So it says "Thanks for visiting me from." then it's going to pull in whatever landing page that you provided. Now let's create a content tag, I'm going to say content tag. Right now we'll just put it in a paragraph tag pass in this and also this is a pretty short line of code in another way of doing this would also be to create some kind of variable like greeting and pass that in there. And then inside of the actual content tag, you could say greeting and then you can pass in a class. For this one we can say source greeting, this is a CSS class. We're not going to do anything with it right now but later on when we start styling items this is going to come very handy. So we're going to save.

large

Now we just need to call <%= source_helper %> our source helper and we can now replace it on each of the layouts. And then we'll save on the home page.

Switch here and hit refresh. So far it looks good but remember this doesn't really kick in until we have used this source tracking system so I'm going to go to a localhost:3000?q=facebook hit return and there you go. Look at this "Thanks for visiting me from facebook." if I go to any other pages this follows me around the entire time including even when I'm changing layouts. If I click inspect then it will show me that this is added a paragraph tag and added the source screeding right there. And now if you look back at the code each one of our templates is looking much better. This is definitely a better practice. Imagine what happens if we come here, and this is going to happen actually in the not too distant future when we start implementing styles, and we want to add some more styles say some other CSS classes provided by bootstrap. We only need to make that change in one spot and then it's going to be able to be populated in all the other kinds of areas.

I want to add to the ability to have these kinds of content tags and also just helper methods in general and that is that they can take arguments. If I pass in right here an argument so this is going to be something like I can say layout_name and then this would give me like say the reason why I want to do this is because say that I want to have this shown a little bit differently in this page vs the main page vs the blog page. I can actually pass in a basic layout name here and I'm going to say layout name and first source helper. This one can be passed in as a string. So this can just be application. And then for these other ones they can be their own respective ones. So this one will be blog and the portfolio can be. It can be portfolio but we know also let's just keep it up location. Let's pretend that I don't even know. I haven't decided yet. Let's say for the sake of simplicity we want to keep this the same here. Now we can have access to this layout name and we can customize that however we want. If we say if session source and then we have all of these items then I don't really have an idea what I want this to be. I won't until we start to get in the design side but just to make this easy let's say thanks for visiting me from here. And then add and you are on the pass lay out name lay out okay. So I believe all of this should work.

large

If I hit refresh. Look at that says "Thanks for visiting me from Facebook" and "you are on the application layout." Click on blog, scroll down, "You're on the blog layout." That is something where in this particular instance I'm not sure if we're going to really need that but I want to show you it is possible. I have gotten this question from multiple students when I've shown them how you can use view helper methods. One of the first questions is OK how can I pass specific data to the view? The cool thing is, it's just a regular Ruby argument. That's all you need to do. You can treat this like a standard Ruby method, because of that you can treat it like that and pass arguments just like we did right here. So this is all looking very good. I definitely like the way this is getting cleaned up.

  • git status
  • git add .
  • git commit -m "Implemented content tag helper methods"
  • git push origin view

Now let's come and click integrating content helper's is good. Next, we're going to dive back into partials and we're going to talk about how partials can be used with data collections.

Resources