Add Image Upload Field0:05
All right, welcome back. So now why don't we add support for featured images above each idea. So the first step is to update our form, And yeah, maybe right below the description is a file input. Okay, let's go into index, down to our modal. And yeah, maybe right here's description. Yeah, maybe right here. So once again, let's have a diviv with a little space in between the controls.
So once again, let's have a diviv with a little space in between the controls. And what would we have here? Well, at the very least, we would have a file input, right? And this is a file input for images. So let's give this a name of image or something like that and be clear that it accepts images. Now, if we have any upload issue related to our image, let's display an error for the image. And what else do we need here? We need a label for image.
let's display an error for the image. And what else do we need here? We need a label for image. Let's give a class of label. And this is our featured image. All right, let's take a look in the browser. All right, scroll down. Yeah, this is what we have. Okay, so now I can choose a file. Now, behind the scenes, I've actually added some example thumbnails that we can use for this course, and they're actually, uh, real life Lyrica course thumbnails.
Set Form Multipart Encoding1:19
and they're actually, uh, real life Lyrica course thumbnails. So yes, I can select one, but as you may know, if we're going to allow for file image uploading, then we need to tweak the form itself. So we should do that. Now, Let's scroll back to the top and where we define our form. Yeah, we can do it right here. Let's set the encoding type to multi-part slash form data.
Validate and Store Upload1:37
Yeah, we can do it right here. Let's set the encoding type to multi-part slash form data. Okay, so now that image will be sent to our server. So that means if I go into idea controller down to the store action, it'll first go through our form request. And right down here, let's check for it and validate against it. The image should be, uh, it can be knowable. You don't have to include one. I do want it to be an image.
The image should be, uh, it can be knowable. You don't have to include one. I do want it to be an image. And let's set a max of like five megabytes or something like that. All right, so now back in idea controller. Yeah, once again, as we always do, let's die and dump all of the request data and see what we have here. Let's add a title here, upload an image, scroll down, create. And sure enough, yes, we have the title,
scroll down, create. And sure enough, yes, we have the title, the status description, but we also have an uploaded file instance. So you're gonna love this. Avil makes this wildly easy to persist. So after we create the idea and we associate the steps, yeah, so now I can just say request image store to an uh, folder called ideas.
so now I can just say request image store to an uh, folder called ideas. And I want these publicly accessible. And that's it. It's pretty cool. So let's give it a shot. Let's refresh. And oh, yeah, we, we did run into one issue. Now, because we are appending to our attributes, well, we're trying to associate image with idea and we can't do that yet. So one more time, we will tweak this in a little bit, but let's exclude those for now one more time.
So one more time, we will tweak this in a little bit, but let's exclude those for now one more time. And yeah, so now we have a new idea, but check this out. Here's where the image is uploaded into the app folder. It is publicly accessible. Here's the ideas folder, and there is the image that we uploaded. It's so easy, okay? So notice how it has a unique name. That's fine. Of course you can override that if you want, but it's okay.
That's fine. Of course you can override that if you want, but it's okay. So now what I can do is if I switch back here, this will basically be my image path. So think about it. Once we have stored that image, I could then say, even if we do an, uh, an additional request, I could just say, all right, update this. We're gonna set the image path equal to the uploaded image path.
We're gonna set the image path equal to the uploaded image path. And now every idea has an image it is associated with. Don't forget when we, uh, created the migration, we included an image path. So we're all set. Now we're gonna test this out, but also I want you to start noticing that it's beginning to appear that there's a number of steps involved with creating an idea, and it's all kind of locked behind this controller action.
with creating an idea, and it's all kind of locked behind this controller action. So for example, if I ever wanna create an idea from elsewhere in my code base, uh, if I wanna let AI do it, if I wanna do it from the command line, if I want to test it easily, ugh, it's a little bit tricky, right? So it would be nice if maybe we had a dedicated class that was responsible for creating the idea. So just file that one away for a moment. Let's come back. I'm gonna try it again. Give it a refresh.
Display Image on Show4:35
So just file that one away for a moment. Let's come back. I'm gonna try it again. Give it a refresh. All right, let's have a look at table plus. And of course we have some, some gibberish ones where we were playing around, but you can see that we now have, uh, a new record with an image path. Okay, so now I want to access that image from the view. Let's go into our show page, and I think we'll show the featured image above the title. Alright, so let's do a check.
and I think we'll show the featured image above the title. Alright, so let's do a check. Let's say, well, do we have an image for this idea? 'cause it's not required. But if we do, then yeah, I want an image here. And now I can't simply just do this, right? Because it is a relative path that assumes, uh, a storage directory. So for example, if I come back and we open one of these, yeah,
Create Storage Symlink5:22
So for example, if I come back and we open one of these, yeah, we don't see anything at all. Okay, so here's how we tweak that first from the terminal, we are gonna run PHP Artisan, and you're gonna look for a storage link command notice, it creates the symbolic link configured for the application. So yeah, just remember when you upload the image, we set it up where it goes into the storage directory. That's not accessible, of course, from the public folder,
we set it up where it goes into the storage directory. That's not accessible, of course, from the public folder, uh, the document route. So we can set this up by saying storage and create a sim link there. And now notice there's a public storage link that was created. Okay? So if I come back, public storage ideas and notice this is a sim link. Uh, so we can access those images there. Cool.
and notice this is a sim link. Uh, so we can access those images there. Cool. So now let's just tweak this. I want an asset. It's in the storage directory, and here is the path, uh, from that point. I think that's right. So let's cross our fingers and see if it works. Come back, refresh. And there we go. We have our image. It looks great. Do we have one for one of these others? I don't think we do. In which case we don't
It looks great. Do we have one for one of these others? I don't think we do. In which case we don't see the image at all. This is working. Okay, so now I just wanna tweak the presentation a bit. First up, why don't we wrap this within a div and then we'll add, uh, just a couple classes. I want this to be rounded. And then let's hide anything outside of view. So if I come back, now,
And then let's hide anything outside of view. So if I come back, now, you can see we have some rounded corners. It matches the layout of it. Next on the image itself, this could be, uh, some different sizes. So what I think we should do is, uh, add a class and say, okay, it needs to be the full width, the height can be auto, and then let's do maybe object cover.
the height can be auto, and then let's do maybe object cover. So let's use, uh, this like background cover, if you've ever done that before. Uh, for the image, it'll make sure that it is presented nicely. And in this case, it's, it looks good. Let's go to full screen. Yeah, I like it. Alright, so let's create a new one. Let's create it and open this up.
Show Thumbnail in Index7:22
Alright, so let's create a new one. Let's create it and open this up. And now we can see it. It's working. Okay, so next it would be cool to also see this on the idea card itself. So let's do that one as well. Let's go into our index view. Have we extracted an idea card yet? Nope, not yet. And that's okay. So here's our card. And notice it has the title and the status, the description and the timestamp.
And notice it has the title and the status, the description and the timestamp. Notice right here. Title, status, description, timestamp. Okay, so why don't we place the image once again, just above it. So yeah, right up here at the top. And yeah, we've already written this, so I'll just paste it in exact same thing as we had before. And there we go. It looks good. Okay, so now just a few things.
And there we go. It looks good. Okay, so now just a few things. Of course, we want a little spacing below the thumbnail. And then I do want it to extend to the edges of the panel, so it looks like it's right up against that border, uh, rather than, uh, Ted. So let's do this on the div that surrounds the image, uh, push it down a little bit. Or we could do March in top four here. Well, actually I don't wanna do that
Or we could do March in top four here. Well, actually I don't wanna do that because there may not be an image. So we'll do it here. Uh, negative MX four, that's like adding negative margin to push it to the edges. Um, same thing for the march in top. Make it rounded only on the top, and then hide anything. Yeah, this all looks pretty standard. Fair. There we go. Now it's pushed down. I can see the rounded edges here. I think this looks great. Okay,
Now it's pushed down. I can see the rounded edges here. I think this looks great. Okay, so I think we're 95% of the way there. Once we start building the edit idea modal, which I kind of wanna use the same thing, spoiler alert, we would need to add support for, uh, for example, deleting the featured image. How would I remove that? What is involved in that? And then next, for the following episode, I wanna return to this idea controller.
Plan Action Class Refactor9:08
And then next, for the following episode, I wanna return to this idea controller. And yeah, we were talking about this, it's just starting to become a thing, right? There are steps involved with creating an idea and there's more to come. So with that in mind, why don't we create a dedicated action class? I'll see you then.
I'll see you then.
