This episode is for members only

Sign up to access "Build a Forum with Inertia and Laravel" right now.

Get started
Already a member? Sign in to continue
Playing
06. Basic discussion listing

Episodes

0%
Your progress
  • Total: 6h 54m
  • Played: 0m
  • Remaining: 6h 54m
Join or sign in to track your progress
01. Introduction and demo
6m 59s
0%
02. Getting set up
10m 36s
0%
03. Modifying registration for usernames
7m 15s
0%
04. Figuring out the forum layout
5m 57s
0%
05. Creating and listing topics
9m 15s
0%
06. Basic discussion listing
13m 33s
0%
07. Pinning discussions
4m 1s
0%
08. Tackling pagination in Inertia
8m 23s
0%
09. Customising pagination text in Laravel
52s
0%
10. Showing a discussion
6m 4s
0%
11. Setting up discussion posts
5m 53s
0%
12. Listing through discussion posts
5m 28s
0%
13. Adding more data to posts
8m 24s
0%
14. Adding pagination to posts
1m 35s
0%
15. Adding a post preview to discussions
4m 52s
0%
16. Adding the last reply to discussions
5m 54s
0%
17. Outputting discussion participants
8m 4s
0%
18. Limiting participants in the UI
5m 56s
0%
19. Ordering discussions by last post
4m 30s
0%
20. Handling deleted users
2m 31s
0%
21. Counting replies
8m 13s
0%
22. Building our first filter
8m 31s
0%
23. Highlighting current filters, and merging with pagination
5m 37s
0%
24. Adding auth specific filters
6m 40s
0%
25. Adding the topic filter
8m 18s
0%
26. Scaffolding the new discussion form
13m 29s
0%
27. Toggling the create discussion form
9m 2s
0%
28. Keeping form state
4m 59s
0%
29. Storing a new discussion
11m 29s
0%
30. Discussion validation and authorization
5m 1s
0%
31. Generating markdown for posts
8m 37s
0%
32. Toggling the markdown preview
7m 43s
0%
33. Fetching and displaying markdown
8m 6s
0%
34. Adding a markdown shortcut toolbar
5m 53s
0%
35. Dealing with SVG icons
7m 46s
0%
36. Creating the reply form
7m 48s
0%
37. Basic Inertia permission checking
6m 26s
0%
38. Creating replies to discussions
5m 37s
0%
39. Jumping to posts
11m 40s
0%
40. Automatically scrolling to posts
6m 18s
0%
41. Toggling post editing
7m 32s
0%
42. Editing posts
3m 36s
0%
43. Deleting posts
4m 21s
0%
44. Deleting discussions
6m 7s
0%
45. Setting up for best answers
7m 29s
0%
46. Toggling the best discussion answer
12m 14s
0%
47. Solved and unsolved filters
2m 23s
0%
48. Indexing discussions for search
8m 6s
0%
49. Searching discussions
12m 35s
0%
50. Debouncing search
2m 47s
0%
51. Adding mentionable functionality to forms
6m 32s
0%
52. Indexing users for mentioning
9m 9s
0%
53. Hooking up users for mentions
10m 10s
0%
54. Detecting and storing mentioned users
9m 54s
0%
55. Adding the mentioned filter
2m 26s
0%
56. Adding mentions to the markdown toolbar
1m 1s
0%
57. Adding mentions to the reply form
7m 21s
0%
58. Fixing up some unauthenticated state
1m 1s
0%
59. Fixing up post scrolling
1m 48s
0%
60. Reviewing SSR (Server-side rendering)
8m 20s
0%
61. Preventing parent posts from being deleted
2m 31s
0%
62. Improving solution marking
4m 9s
0%

Transcript

00:00
Let's get a basic list of discussions output on the forum index.
00:05
Once again, the first thing that we're going to do is create out a model for this. So let's make a discussion model and a migration alongside of that. We'll keep this really simple for now and we'll add some more to this later. So let's head over to create discussions table and let's start to add in what we need.
00:22
We know that a discussion is always going to relate to a user. So we're going to use the foreign ID method here to hook this up to a user. And here we're actually going to make the user nullable. Now, the reason for that is later on, we're going to allow users to be deleted,
00:37
which already exists within Breeze. But we're going to detect this and show if the user has been deleted. When a user gets deleted, we want to keep all of the discussions just for historical purposes, but just get rid of any of the user information alongside of that.
00:52
So we'll make that nullable. We'll go ahead and make this constrained within the database. And we'll go ahead and say on delete set null. So when a discussion is deleted, this column gets set to null.
01:05
Next up is the topic itself. So again, this is quite simple, a foreign ID with a topic ID. And we will just constrain this. And we're going to assume that topics are never deleted.
01:16
So we are not going to set any kind of cascade on that. Next up, again, simple the title. We need a title for the discussion. And we also need a slug as well.
01:28
Now, this is going to be unique. But this is also going to be nullable as well. And that just means that when we create out a topic, we don't initially set the slug. But then we generate a slug based on the topic ID that's been created.
01:43
That's just because if we think about the way a forum works, if we have slash ABC, for example, that would assume that the title of the topic is ABC. So when another user creates another topic with the title ABC, there is going to be a slug collision.
02:00
We know these need to be unique. So what we're going to do is prepend on the ID of the discussion. So it keeps everything nice and unique. Of course, that's not found at the moment because we've not built it.
02:10
OK, so that's the reason that we've got this set to nullable. And we're pretty much done. That's all of our basic discussion data. Let's go ahead and migrate this.
02:19
And we can start to first of all, create out an API resource for this, because once again, we're going to be utilizing API resources to make this easy to extract only the data we need. So let's make out a resource here.
02:32
And of course, we're going to call this discussion resource. And let's head straight over to that discussion resource just to output the data that we need. Now, we're not going to be using that handy this only trick in this time.
02:46
That is just because we're going to be setting up some relationships in here. We need to know which topic this particular discussion relates to. So we will just do this manually. So we're going to need the ID in here and the title of this.
03:03
We'll also go ahead and output the slug here as well. And we also want to hook this back into a topic. So we want to be able to see the topic that this was actually posted in. To do this within an API resource, we just use topic resource like we normally would.
03:18
We use the make method, and then we pass in the relationship. But what we're actually going to be doing is saying this when loaded, which makes us actually eager load this before it's displayed. It's just a little bit of protection.
03:32
If we don't specifically choose to load in the topic for each of the discussions and eager load them, it just won't be shown. So I think that's pretty much it for our basic discussion resource. What we can now do is head over to our forum index controller and just start to pass these down.
03:47
So it's going to be the same as what we did for topics. Let's output our discussions here, use our discussion resource. And of course, this is going to be a collection of topics or a collection of discussions. So we're going to say discussion get.
04:03
And let's go ahead and just add in some other bits in here. So we're going to say with topic, we want to eager load that topic in. And I'm actually going to paginate at this point, because we're going to be adding that a little bit later.
04:17
So let's say 10 items per page. There's a load of other stuff that we're going to be doing in here eventually when it gets to things like filters, ordering by whether something has been pinned at the top of the forum, but we'll leave it like this just for now.
04:32
So if we head over, of course, nothing changes. But what we can now do is head over to our forum index page and start to output these within this main section or this main section just here. So let's look at our container here.
04:45
We've got a background white here. So we're actually going to take all of this and let's just collapse that down. Down here, this is going to be each of our topics. So let's just re-indent this and that's going to be a discussion.
04:59
Sorry, I keep saying topic. I mean discussions. Great. OK, so let's wrap all of this because we want a little bit of spacing here
05:06
or let's actually create out a wrapper around this and then go ahead and set a margin on the top here. So set a margin on the top to say 8. Actually, let's go with the original idea because spacing by
05:24
everything works a little bit better. So let's go and create a wrap around this. And then what we can do is on the outer container set a space y of, say, 6. And there we go.
05:39
Everything's nicely spaced out. Now, before we start to output data for each of our discussions, we're going to create out a discussion component just so everything lives within that particular component.
05:50
So I'm going to create out a forum folder and inside of this, a discussion component. And inside of this, a discussion component. Let's create out the template for this. And we can actually take that directly from this just here.
06:05
So we can copy all of this over to here. And then let's go ahead and create our script section and make that script set up. And we want a discussion to be passed in under our props for this. So let's go and use define props,
06:22
except in a discussion, which is going to be an object. OK, so now that we've done this, we can nicely get rid of all this and just use the discussion component, iterate over this discussion component and pass each of the discussions down.
06:39
So let's go and just pull in the discussion component. First of all, from forum. And we should be good. We should see pretty much the same thing.
06:50
Great. OK, so let's dump out the data that we've got for each of our discussions in here. And make sure we add these to define props. Because they are being passed down now.
07:07
Discussions. And that's going to be an array. And let's head over and check this out. Great.
07:13
So actually now we have an object here because we have data wrapping. We turn data wrapping off, but because we're paginating this, we get the data within the data and then we get our links and our meta objects as well with all of the pagination stuff, which we'll use later.
07:31
So we don't have any discussions at the moment. So we're just going to just generate out a few example discussions. We'll set a topic here and we'll just say need help with Laravel. And we'll set the slug to anything because we haven't got to the generation
07:47
of this at the moment with Laravel. Set the created at and updated at date. And we'll save this. And then we will duplicate this and just change this to view.
08:00
Just so we have something a little bit different. Re-add in the created at and updated at date. And we'll change the topic as well. So let's save that out.
08:11
And there we go. So we have an undefined relationship on our discussion, which makes sense. So let's go over to our discussion model. And let's just create a topic relationship on here.
08:27
And this belongs to a topic. So we just need a really simple belongs to relationship here for that topic. And that should be good. The reason we get that error is because remember over in the discussion resource,
08:41
we are referencing the topic relationship. OK. So now that we've got this, you can see that we've got all of the basic data we've added. And because we've egoloaded the topic, we have the topic for each of them discussions as well.
08:54
So now all that's left to do is just iterate through these and then just start to output the data for them. So for each of our discussions, we want to go and say discussion in discussions.data. We'll go ahead and give this a key, which is just going to be the discussion ID.
09:14
And we're going to pass the discussion down as a prop to each of these as we iterate through them. So now, of course, we have two components here. What we can do with this is just for some sort of visual clarity, wrap this and change the spacing on the y-axis,
09:35
just so each of our discussion sits a bit closer, but it's further away from the top here. OK. So over in the discussion component, we can now start to output any information about this discussion that we want.
09:48
Let's just start with the title and just see this roll in. And there we go. We've got them two in there now. And we can just start to output any of the other information we have in here.
09:58
So inside of this container, we're actually going to have a left and a right section. So we've got a div here and a div here with things like the participants' avatars. So let's just say avatars. And we'll leave it at that.
10:14
For this outer container, let's set flex and item center. And we'll set the space on the x-axis to six. So we have a little bit of spacing between these two things. That doesn't look much different.
10:25
But of course, we now have this avatar section here as well. For this side, we want this to grow. We want this to be the prominent section. So for this outer container, we'll set a flex grow to this.
10:37
And that will just push this out. And then avatar stays on the very right hand side. So for the title, once again, we want the topic of this to sit here and then the title next to it. So again, we're going to create out a container in here, which is going to be a flex container.
10:55
We're going to say item center. And we'll set the space on the x-axis to three. So now what we can do is add in an h1 for the title. So let's just move that over.
11:06
And we can have the topic in here. So that looks like this. We've got the topic here, title right next to it. So let's just style up the h1 really quickly.
11:15
We can just make this really simple text large and font medium. And there we go. And then for the topic, we need to extract that topic data and then output it. So for this, we just want to say discussion topic title.
11:30
Easy as that. And we now have or we should have the discussion topic there. Let's just dump this and see what's going on here. We may have forgotten to include it somewhere.
11:40
And yeah, we called it name. So yeah, that's OK. We'll stick with name. In fact, let's switch this to title because everything else is title.
11:50
That kind of makes sense. So if we go over to our database and the topics, let's just switch this to title. We'll modify that in our migration as well. So under create topics table, let's set that to title.
12:04
And then, of course, over on our forum index, we have topic name being used or referenced. So let's change that to title. And that should be good. Yeah, we just need to modify our topic resource and we're done.
12:18
So title. And yeah, we also need to update our handle inertia requests to order that by the title. OK, there we go. It's a good point to do that now rather than later when it's everywhere.
12:32
OK, so we've got our topic title inside of here. Let's just really quickly style this up. So let's set this to an inline flex. So we have this inline, but we can also use things like item center and just center this out.
12:46
We'll set rounded to large on this. Let's set the background to gray 100. I'm going to add some padding on the X axis and padding on the Y axis as well. Just set that to half.
12:58
We'll make this a little bit smaller so it's not as prominent. And we should be good. Text will set to a much darker gray. OK, let's have a look.
13:08
And there we go. We now have our topic output as well. So that's pretty much it for now. Of course, we've got a whole load more to add to this.
13:14
The first post body preview when the last reply was and also the participants avatars and how many replies there actually are. We'll get that along the course, but at least now we have a list of topics actually output, which means we can start to work on things like pagination, filtering, all that kind of stuff.
62 episodes6 hrs 54 mins

Overview

Ready to build a forum with Inertia and Laravel?

Why a forum? A forum touches a whole load of concepts that you'll use throughout your development career – particularly on the client-side, where we'll be doing most of the heavy lifting.

So, let's build a clean, modern forum with features like markdown support, code highlighting, advanced filtering, user mentions, full-text search, the ability to mark best answers, and more.

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!

Episode discussion

No comments, yet. Be the first!