- Read Tutorial
- Watch Guide Video
In this section of the course, we are going to start building our rails views. Starting in pivotal tracker, I'm going to click rails views and I'm going to drop it right into our current backlog. I'll click start and let's go take a look at the tasks that we have.
We're going to be working with the master layout file. We've already talked about it a little but we're going to go into a deeper review and we're going to do all kinds of cool view things such as work with view helper's, content helper's, work with data collections in the view and things like that. This is going to be a very fun section.
Switch over to the terminal, I'm going to change into the devcamp-tutorials/DevCampPortfolios and change into the application. I did some side development on the Devcamp Site between the last video and this one. I'm also going to switch over to the other version of Ruby. If you see on the top right-hand side, I'm using Ruby 2.3.1 but we want to use Ruby 2..4.0.
Right now we are on the master branch and we're going to perform all of this in a feature branch. This is going to be called our view branch git checkout -b view
hit return we've been switched to the view. Let's open up sublime text. I'm going to close out these files so we can start scratch. In our controller section we talked a lot about using the application controller and how essentially everything inside of the application controller was accessible by the child controllers.
You also may have noticed that in our views, you go to layouts, we have an application layout view. This is not like the application controller. Your app is probably only going to have one application controller. However, you most likely are going to have multiple layouts. Your application layout can be kind of like a base one for us we're going to use it for the main layout that most people access when they see the site. Technically, you don't really even need to call it application layout. You can create any number of layouts and have all kinds of custom layouts and then call those in the controller.
By default, rails uses the application layout file and we're still going to keep it but I just want you to know this is not like the application controller where everything inherits from it. This is simply an HTML file that by default the data gets sent through in the view. That's what we're going to talk about a little bit more now.
You can see at the top this is just regular HTML boilerplate. We have a doctype of HTML. We have a head element and then inside of the head element we have title tags, say that we didn't want to call this DevcampPortfolio like this but we wanted to do something like say Devcamp Portfolio | My Portfolio Website. If I hit save, and start up the rails server, we can switch over to chrome and hit refresh.
You can see right up top this now has the title of Devcamp Portfolio | My Portfolio Website. In the title tag, you can put anything that you want. since it's your portfolio you probably want to put your name. This is something that you can control.
Another cool thing is that you can actually set this dynamically, right here this is hardcoded. Let's say that I want to go to blogs, I go to localhost:3000/blogs, notice here that the title still says "My Portfolio Website." That is because this is hard coded into the title but it doesn't have to be. We can customize this if we want. That's what we're going to do.
Open the application_controller.rb file and you can see here that we have all of our nice items. This is where we can set our main default value, I'm going to cut this out and in our application controller I'm going to say:
before_filter :set_title def set_title @page_title = "Devcamp Portfolio | My Portfolio Website" end
In our application layout view file we can use embedded ruby and pass and page title hit save and now comes here.
Let's see if this works, everything works as it normally would.
Let's change this up because page title is an instance variable we can change it. In our application, we're setting a default title. This gives us the main default but we also have the ability to go and change it on other pages. let's open up the blog controller and we're going to go inside of the index action. We can come right inside this index action and paste in @page_title = "My Portfolio Blog"
hit save and if I come back to Google Chrome, you can see that the title has been changed to "My Portfolio Blog". If I go to a different page like click on new blog you can see it switches back.
This gives us the ability to have a default title and then any time that we want to change it we can just add this page title and overwrite this in whatever action it is. We could do this for the show page.
Here instead of pulling the title and hard coding, I can actually do:
def show @page_title = @blog.title end
remember we have access to the blog instance variable because of the before_action. before_action calls set_blog which is the method all the way down here, that's the reason why we have access to that. I'm not just calling this out of the blue. Technically, this is like we have a call to @blog that happens even before all of this runs.
I'm going to hit save and let's go back and click on show page
Our title now says my blog post which is the title of this. That show how easy it is to override the values and to implement some pretty cool customizations with just a few lines of code.
Let's do our usual pattern here and let's move this into its own controller concern. Come to concerns and click new file. I'm not going to be so specific to say default page title, what if we want to set other items? We don't want to create each one of our modules with only a single method, we could do things such as implement search engine optimization dynamic tags on every page or something like that and we could have our default one set in here. In this case, I'm just going to say default_page_content.rb
Now here we can say module DefaultPageContent and inside of this, we need to import active record concern.
module DefaultPageContent extend ActiveSupport::Concern included do before_filter :set_title end def set_title @page_title = "Devcamp Portfolio | My Portfolio Website" end end
Now we can just add include DefaultPageContent
into the application_controller.rb
Let's come back here and refresh, everything is still working. Now we have the ability to set all of our items. This is called set_title, I'm not sure if I want this or not. What if I want to just do something like say set_page_defaults because now can set other page items. If you've ever worked with search engine optimization there is something called key words that you can have access to inside of the tags and there are things that search engines like Google or Microsoft will look at.
This seo_keywords instance variable is going to be available for us anytime that we need it. Even though I changed this method, this was the only spot where it was called so everything here should still work perfectly fine, which it does.
Let's come back and I'm going to open up the application.html.erb file and inside of the tag there is a spot for this and this is when I always have to look up. let's follow the same pattern I do if I was building a real app. In Goggle, look up seo html keywords. This should give us the spot where to put them and all of that. let's see.
In the application.html.erb file add <meta name="keywords" content="<%= seo_keywords %>" />
Let's come to the site and let's check it out. If I hit refresh, no errors and you're not going to see anything on the page because this is something behind the scenes that the search engines look at. I can just click View page source right here and look at this
meta keywords and it has exactly what we placed inside of that.
We can make this dynamic too so we can have this kind of being like our default set of keywords. What if we want to add in our blog another set of keywords? I'm going back once again to our blog controller, inside of show maybe we want to have @seo_keywords = @blog.body
. If you were really concerned about search engine optimization then you'd actually create a separate field specifically for this inside of the blog model and it would be called Keywords.
That's what I did with Devcamp where it has an entire field just dedicated to search engine optimized keywords and then I pipe it right into an instance variable exactly like this.
Let's come back to the site, go to the show page because on every other page it's just going to be using the defaults. If I click Show and then click on View page source
you can see right here are the meta keywords are the body. Once again that's not the right way to do it. In search engine optimization you usually are going to only put seven or eight words but this kind of goes to show you how you can set all of those items dynamically. The way the data flow works, even though we have it and we're calling in the application controller, notice how everything starts here in the master layout file. This master layout file is where we can set the page title for the entire site, it's where we can put in our search engine optimization items all in the head. Then moving down, we have our body tag. This is where all the magic happens in regards to what you can see on the page.
If I were to come inside the body tag right here and just put a tag, hit save. This is going to be available on every page of the site, you have that content there, of O click edit, It's still there. It's going to be there on every site that uses this application layout file, for right now that's all of them.
We've already talked about because we've implemented these items such as the alerts and our little login links, those kinds of things. The application layout file is also where you would put navigation items and we are going to do that later. For right now let's kind of mimic this a little bit. I'm going to just create a inside of it. Let's create a few other subtypes of . We are going to create one and end it off. Let's just create just a couple more and I'm going to put some links inside and say link underscore to home and here we can say root path.
Next, we can have a few other items, if we look at our pages controller we also have an About page and a contact page and if we open up our routes we can see the types of routes that we have. This doesn't really give us exactly what we need because we also need to know what the the helper method is. if you remember whenever we have a question about routes we can close this out and just type rake routes and I'm going to do a search called grep which is going to filter by pages. This will bring up all of the items that have pages in there. And that has the pages controller. Here we go we have about me, contact and route. We actually have a method called about me. And then when called contact so that's all we have to use.
Start the rails server again. here I can say about me path and for our last one right here we can do this one for contact.
Let's see this, it's going to be ugly but it is going to serve our purpose. We have home, about and contact. If I click on contact it takes us there but our links are still in place so this is very important. Imagine if you didn't have an application layout file you'd have to copy and paste this into every page of the entire site and then say the 30 pages and then you wanted to add one more navigation item you'd have to go in make 30 different changes. That would be a horrible way of building a site.
Here we only have to put it in one spot. If I switch over and go to about I can go home I can go to contact and if I want to make a change, say that we have contact but we also want to point people to our blog, say just go to a blog and then send them to the blogs path and save refresh.
Now we can get to our blogs. We can do the same thing with our portfolio
It's going to be much easier for us to navigate to each one of our items. Don't worry I know this is ugly. We're eventually going to have a nice modern looking type of navigation bar that's going to have each one of those items but we'll save that for our styles section.
We've already talked about our little conditional here that checks for a user and chose either the logout links or the register and log in once and the last thing that I want to cover is yield.
Yield is probably one of the most important things on the page right now because watch what happens if I get rid of it. No error occurs but all the content disappears. That is how Rail's works in regards to its application layout file. It leverages this yield and from a data flow perspective what happens is the application layout file loads and then whatever page we go to simply slides in right inside of this yield method.
Let's go to the portfolio page right here. We can see all these portfolio items, as far as what the application sees it sees all of this content. if I were to click view page source you can see that has all of the content, all of that data that we put in, our images and all of the HTML code. What is happening behind the scenes is yield simply yields, it gives way and lets you slide in whatever HTML file you're calling.
For the example of the portfolios, if I come to portfolios index it is essentially the same as if I copy this and paste this in right here instead of yield. I hit save and come back you see everything works. Nothing else will work and you'll have a bunch of errors on the rest of the site. As far as what's happening in the background this is exactly what's happening. The yield gives way and allows you to slide in any of the other templates that are being called. That is a very important thing.
If you have never seen that before then that may seem a little bit odd but that's the way that you're able to dynamically slide content in and be able to use a master layout file.
I think that was a very comprehensive view of the things that you can do inside of the application layout file.
- git status
- git add .
- git commit -m "Added nav bar and added default header content."
- git push origin view.
We can come up to a pivotal tracker and knock out the working with the master layout. Excellent job doing that.
In the next guide, we're going to talk about how we can create a secondary layout file.