Module 1 - Introduction
1. Welcome to the course2. Why Go3. Why start and build a blog?4. What about React/Vue/Angular?5. Getting setup and source filesModule 2 - Tech Stack Walkthrough
1. Introduction to Golang Part 12. Introduction to Golang Part 23. Introduction to Golang Part 34. Structuring Golang Applications5. Templating with Templ6. Just enough interactivity with HTMX7. Getting started with postgres8. Servers, routers and endpointsModule 3 - Creating the MVP
1. What are the minimal requirements?2. Doing some initial plumbing3. Embedding static assets4. Creating our first views5. Tailwind & Utility-first CSS6. Styling the Landing Page7. Styling the Article PageModule 4 - Managing Content
1. Choose your own adventure2. Writing in Markdown3. Parsing Markdown to HTML4. Frontmatter and Meta Information5. Making our code examples look nice6. Adding error pagesModule 5 - Adding the Database
1. What is a Migration?2. Our first migration: articles table3. Creating the Database Layer4. Showing the Latest Posts5. Slugs and Human Readable URLsModule 6 - Managing the Blog
1. What are the minimum requirements?2. A new layout approaches3. Introduction to authentication4. Our second migration: Users Table5. Storing passwords securely6. Authenticating users Part One7. Authenticating users Part Two8. Remember me/Forget me9. Managing posts using a hypermedia API10. Our third migration: Altering Posts Table11. Only show posts marked readyModule 7 - Adding Subscribers
1. What are the minimum requirements?2. Our fourth migration: Subscribers Table3. Creating the subscription form4. Adding some interactivity with HTMX5. Saving new subscribers in the database6. Verifying subscriber emails7. Our fifth migration: Tokens Table8. Email validation view9. Email validation tokens10. Sending validation emails with SES11. Making it all come togetherManaging Content
Frontmatter and Meta Information
Summary
In this video, I show how to handle front matter for articles using Goldmark's built-in extensibility. I demonstrate how to add YAML support through the goldmark-front-matter extension and create proper data structures to handle metadata like title, date, description, and tags. I explain how to update our views and controllers to work with the new article structure, and show how to implement suggested articles functionality by comparing slugs. The video concludes with adding inter-page linking, which I explain is important for SEO and keeping users on your site, as it signals to Google that your content is valuable.
Transcript
o it's actually quite straightforward to start parsing and handling FrontMatter for our articles. And this is because Goldmark has this built-in concept of extensibility, which basically means they provide us with a bunch of interfaces. And if our package or library has fulfilled these interfaces, then we can add them as extensions. And one of those extensions is this one here called Goldmark FrontMatter. And this simply just add YAML and TML support. We're only going to need YAML for now, but you have the option of doing TML as well. So let's grab this installation here. There we go. Jump into our terminal. And then add it to our go.mod file. Then in our articles, we can now go ahead and add a new variable called Goldmark new. And this is because we don't want to now call Goldmark directly. We want to create a variable that we can then pass some options to. And if we look at the function signature for new here, we can see that they're taking a bunch of options. And let's just take a look at these options. So this is basically the markdown, the private markdown struct in the library, right? And it has these extensions right here or extender, which is just an interface that then extends another interface called markdown, which is the one we really care about, because this is the one that allows us to do extend Goldmark with whatever we need. So with that in mind, we can say, we go ahead and say Goldmark with extensions, and then we say frontmeta.extender. And now we can go ahead and replace Goldmark and use our empty variable instead. Great. So we still need to output the content to our HTML here, but we need the new parser or the new extension to be aware of the context of which we are doing this operation. So let's just create a parser context and actually create it directly. Say parser new context, then simply pass this to the convert. So we say parser with context, parser context. There we go. Great. But we also need to specify a proper data structure now, because we are no longer just returning a string. We are actually returning metadata. So let's create one here called article. That's a struct that has the type of content, which is just a string as before. And then we want to have this meta field here, which is of type meta that we're going to create now. Meta struct. I can hit the, there we go. I'm just going to copy in a bunch of fields here. So this is basically what we talked about in the last video, right? We have title, date, description, tags, locks. And then we specify the name in the YAML file. And our new parser will know exactly where to pull this. So now we can go ahead and say var meta meta. And again, if error equals, and we say frontmeta.get, and we get it from the parser context, and then we decode that into meta. And say if error equals nil, then we say return as before. So final thing here, or almost final thing, is we need to return an article now instead of a string. So let's just return an empty article in case there's an error. And if you have no errors, we can actually return an article where the content becomes article string as before. And our meta simply becomes our meta, and nil, there we go. And we'll have a couple of errors now. And that's because our get and getAll functions both still return a string. And we just need to update this to be article for get. And then also, let me just go ahead and grab this one to update what we're returning in case of an error. Now, our getAll functions, we need to do a little bit more because we now need to return articles, not strings, as a slice. So we say also here article, article, and we're still looping over the files. But instead, we say article error. And let's just use the get here to say file name. Name. And we actually need to still split it, so like this. Because in the get function, we add the extension. So this in place, we can now say return nil or error if we can find the article. And then we append to articles instead of file names. And we just grab the article that we just pulled out. There we go. Article small. And finally, we just return the article. There we go. With that in place, we can go ahead and update our views. And let's begin by updating our home page component here that is now going to be receiving a slice of articles. And we also are going to be looping our articles, not files. And then we simply just update the data we pass under the article.meta field. And we're going to pass title. We're going to pass description. And we are going to be passing the slug here. So that is, oh, need to say articles, article. There we go. So this is pretty much how our home page component is going to look like. Our article page is going to be very similar. We are not going to be passing title and content. We are going to be passing an article directly from our package as well. And now, as you probably guessed, we simply just say article meta title. We say article meta date. And you could also update the metadata to include an author name. I'm going to be the only author, so it doesn't really matter. And finally, in the unsave function, we pass the content. Awesome. Our controllers. For the home controller, I'm just going to update this one here to be articles instead of a file name. So it's a bit more clear as to what we are passing. And then in the article controller, we just need to remove slug and we are good to go. Then we can finally go ahead and add our front meta to our articles, which you just pass in the top of the file like this. So we just pass this where you do three dashes at the top of the bottom. And then with the text that we added in the beginning. And now if we go ahead and restart our development server, so it picks up the changes to the markdown file, we can go in here, give it a refresh and we actually see we have the correct title. We have the description and then we have read article. And if we jump into it, we can see my first article. We have the date and the subheading and everything is as before. So our front meta is looking great. The only thing I want to touch upon now is that we have distilled this hard-coded other articles and now with the front meta, we can actually quite easily add these suggestive articles. So let's go ahead and do that. As I do that, we simply just upgrade our article page component. We add in another argument here. Let's just call this other articles. That's going to be a slice of article. Get rid of this hard-coded list element and then loop over these other articles. Arrange other articles to go. Then we just use the other article meta title. Wrap this in an anchor tag that's going to be a symbol. Save URL, fmt, sprintf. Pretty much that's what we did on the homepage. Goes to slash article slash slug. Other article, not title, but slug. Give that a save. And then we just need to wrap the list element. And this is all we need in the article page. We just need to update our controller where I actually made a mistake because this one here clashes with the name of the package. Let's quickly rename this to all articles. There we go. Go up and grab it. Because we're going to be needing this down in the article controller. So grab all the articles. Create a variable called other articles. Again, it's just the type we expect, right? We loop over all the articles. I'm just going to say a here. Since we already have a variable named articles, it's just short for article. All articles. And then we just check if this article that we are looping over the metadata slug. If that is not equal to slug, then we can pass it to other articles. Other articles. Now, be aware that as you add articles, it will show everything. So we'll show all our articles we have right now. For our purposes at the moment, this is fine. But if you wanted to, you could pass the date field from the metadata sorted by latest. So you only have the latest one and don't do the earliest one. And then just have a counter that makes sure that you only add, let's say, five or three or four articles on each page. But for now, this is going to do just fine. Pass the other articles variable. It's complaining my LSB. I think if we restart, it should be better. It is nice. Now, we also need to actually have another article, right? So I'm just going to grab everything from article one to article two. Put it in here. Update the title. Second article. Update the slug. That looks right. Again, we need to restart our development server. So it picks up the new file. And now everything looks right. So if we jump into our browser and give it a refresh, we are still on article run. Right, yes. And now we see my second article that if we click it, we get into my second article. It's great. We can go back. So now we have some inter-page linking, which is really, really important for SEO, but also for keeping your users on your site, because that's a signal to Google that your content is valuable. So this is a nice little thing to have, right? And the final thing we have is this code example here that's looking very blunt. I would like to add some syntax highlighting and some line numbers. So let's tackle that in the next video.