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 API - Part One10. Managing posts using a hypermedia API - Part Two11. Managing posts using a hypermedia API - Part Three12. Managing posts using a hypermedia API - Part Four13. Implementing CRUD For Articles - Part One14. Implementing CRUD For Articles - Part Two15. Implementing CRUD For Articles - Part Three16. Implementing CRUD For Articles - Part Four17. Flashing Ourselves/Providing Visual Feedback - Part One18. Flashing Ourselves/Providing Visual Feedback - Part Two19. Flashing Ourselves/Providing Visual Feedback - Part ThreeModule 7 - Adding Subscribers
1. What are the minimum requirements?2. Expanding the database: Tokens & Subscribers3. Creating the token and subscriber models - Part One4. Creating the token and subscriber models - Part Two5. Creating the subscription form6. Saving and verifying subscribers - Part One7. Saving and verifying subscribers - Part Two8. Saving and verifying subscribers - Part Three9. Emails and Clients - Part One10. Emails and Clients - Part Two11. Emails and Clients - Part Three12. Our fifth migration: Tokens Table13. Email validation view14. Email validation tokens15. Sending validation emails with SES16. Making it all come togetherAdding Subscribers
Creating the subscription form
Summary
Coming soon.
Transcript
All right. So now we have the database, we have the models, I want to start working on a UI. And what I want to do is I don't want to show the subscription form on the front page, but I want to when we visit up in a user visits an article, we're going to count the number of headers that we have. And now we have two headers in this one and in the article one, we have also two headers, right? So if we go back here, and go into articles, number two here, let's just, I'm just going to create a few more headers so we can make it a little bit easier to illustrate the concept. So now we have, we have five now. So let me just restart the server so we can pick up the changes. Now if we go in and look at article two one more time, you're going to see we have a bunch of headers. Ideally, you want to show the subscription form when the user is already engaged with your content. So I want to count all of the headers. And if we have more than two, I'm going to place it after the second one. So it will literally be placed down here when we have the whole thing set up. If you don't have more than two, we will simply just show it after the, after or before the first one. Depending, I'll probably just show it after, after the first one, right? So this is going to be the implementation. And now let's jump in and start creating our subscriber form and the responses. We are going to be using HTMX for this as well so that we show our success message or an error message, depending on whether the subscription went through. All right, so we're going to start here in views and I'm going to create a new file called subscription. I can't spell subscription. Subscription form. There we go. Impagas viewers, of course, and it's going to be a simple subscription form. All right, so what do we want to have in here? We want to have a form element that is rounded with px4, py2, and ptbase200 with a shadow on it. And for our, our htmx pass here, we want to say hxswap, the outer, HTML. We want to target this, so this form. We want to say hx, hx, sorry, to post to slash subscriptions. All right, plural. So whenever we submit this form, we take whatever response comes back from the server and then we replace this entire form with whatever response we get back. All right, now we have already seen how to, to build out these forms, right? So we, we need our input field that holds the, the CSR token, hidden name gorilla, CSR token, and value is CRF token that we of course need to pass as an argument. So it's going to be a string. Then we want to span that says flex, flex and flex call. In here we want the label and we want an input. Finally, we want a button that says join now. Okay, so for our label, we are going to say join my newsletter. Of course, you can optimize this to whatever you need or want. I'm going to say text sender, text white, a little bit of margin on the bottom and make it font semi bold. Underneath this, we're going to have the little hook. Let's call it hook. It's going to be a class text base content. So let's just say no spam, no AI generated content on subscribe anytime. Of course, this can be, these two parts can be a lot better to entice your readers to subscribe, but it gets the message through for now. All right, so the input field is of course going to hold the email. So we're going to say type email. We're going to say placeholder. Let's just say modern at golang block cost com. Then we want to say name is also email. Oh, we need equal sign. It is required. And we want to have a class that says PG base 200. Make a text base content, adding some padding, border, border gray 500 to make a stand out a little bit more rounded and margin on the button. So this is our label, our paragraph, our input. Finally, let's just add a little bit of style to our button here. It's going to take up the full width. Again, we need some padding, border and border base 300, rounded, text white and PG base. Do we have PG base, PG base 300 and on hover we want to see PG base 300 with 30% opacity. Great. And this is a type submit. Cool. So this is basically our subscribe button or subscription form. That we will be injecting into the article whenever our user visits our site. But since we we want to replace this form with something depending on whether or not the operation was successful, we also need to create two components. And I'm just gonna grab the success component here. We could technically create one that handles both success and response, but I like to have have it more explicit also because it's easier to read when you use this in the controller what is what. So our success response here is really straightforward. So this entire thing just gets replaced, just replaces the form tag, form element, says you're in and then that you will receive an email soon. So that you can validate your your your email, right. But we also need one in case there is a failure. And this one is gonna be a little bit similar, almost the same. We're just gonna say let's say oh no, and then we could not subscribe you. Maybe you are already subscribed. Feel free to try again. All right, so this is gonna be the error or failure message that we have. Failure. And what we want to do here instead is to say fx swap again outer HTML. We want to say hx trigger load delay five seconds so it has some time to read the message. The target is gonna be this. And then finally we're gonna say fx hx get slash fragments slash subscription form. So what we're gonna do here is we're gonna add another fragment that basically returns this subscription form. So if there is an error our database, our email client, whatever might happen, we are gonna show this failure message saying hey we couldn't subscribe you, maybe you are subscribed, feel free to try again. This will show for five seconds and then we make a call to our fragments endpoints that will then load in this subscription form so they can either try again or ignore it. But at least it gives them a second chance to subscribe if something goes wrong. So we now are dealing with the subscription case where they actually want to subscribe to our newsletter, they send us their email, we either store them in the database and send them an email to validate their email. And if anything that fails we show them a failure message and load the form back in again so they can try one more time. That's part one of this flow. The second part is that once they have received this email with this confirmation link they of course also need to see something in the UI that tells them that hey, you know, your email is validated and you will now start receiving the newsletters or they need to see a failure message that can be for any kind of reason, right? We might have a server error, the token might have been messed up or it might have been expired. That case we want to say hey, we couldn't validate your email, you know, something happened, maybe an expired token and here is a form to request a new token and this one again here we swap, instead of swapping the outer HTML we swap the inner HTML so we target this diff right here and then replaces all of this with whatever response we get back from the server. So if they want to have a new token they can submit their email one more time and then we already have them stored, right? And then just send that, send a new email that is valid for 48 hours or 24 hours, whatever we end up doing. And the response that they will get back is gonna be this thing right here. So new validation token response, we are just gonna be saying like hey, a new email confirmation link has been sent to email. We could technically have another error here, right? But I think we are deep enough down in the rabbit hole where we're just gonna showcase this one, hey, you know, it's good. We sent you an email, you know, check your email. So this is the flow. They will receive a form, if there is enough headers they will see a form around here that will tell them either hey, we have subscribed you, we sent you an email, please validate it. Or we could not validate, please try again. They will receive an email with a confirmation link that goes into our block that will then render either the validation success or the validation failure with an option to request a new token. Now in the next episode we are gonna be implementing the controllers and showcasing this on the UI. So hopefully start to make a bit more sense what all the work we've been doing so far will end up looking like. But in the next episode we are gonna be saving and verifying the subscribers and then the following one we're gonna be implementing the logic for creating emails and also a client to begin sending our emails to our subscribers.