Laravel 10 Blog with Filament Admin Panel | Part 1

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
I have built fully functional blog with the larval 10 in tolerance CSS the block has admin panel from which you can manage content of your website here's how I did it install and set up Lateral with crl and Docker install filament PHP as an admin template integrate free blog template in lateral query posts and output on the website with pagination create and use text widgets to manage any content on the website add and use meta fields for search engine optimization let's immediately have a look at the demo of the project on the home page we output a latest posts the post has image title description and the text we also have pagination we can go to the next Pages if we want when you open the post in your page you're gonna see the post image categories title and the whole description of the post and right here we also have next and previous patterns and based on that you can navigate between the next or previous posts on the right side we see all categories and also how many posts there are in this specific category in the navigation we have the home page top three categories and about us page if we open URL localhost slash admin and then enter username and password we are in the admin panel right here we can create categories and modify or delete we can also update posts and text wages text widgets are just key value pairs where we can output certain things on the website like for example the header text is output using a text widgets and also this About Us section is outputted using text widgets if we open the post section and click the very first post right here we can change the title and based on the title slag is automatically generated we can change the image assign or remove categories and of course adjust the description of the post and finally we can specify meta title in description mark this post is active or not and specify publish date if the post is not active or published date is not specified or if the published date is in the future the post will not appear on the website I want to give away my laravel e-commerce course there are two things required to participate in this giveaway you must be subscribed to the channel and you must leave a comment down below under this video and use the code holique in your comment I will choose 10 random people as winners and contact them and give my larval e-commerce course for free I'm going to also announce the winners on my Twitter if you want you can follow me on Twitter but it is not actually mandatory all right thank you very much for watching this video so far I really appreciate every single viewer of this video and now let's start building the project now let's start building our project this particular project I'm going to develop fully on Docker if you don't know what is Docker or how to set up it on your operating system first I recommend to check the docker tutorials I will try to use Docker more and more on this channel when building the projects because I think Docker is an essential tool nowadays for every uh every full stake developer or even back-end developer so Docker makes things very very easy and very very safe okay now we're gonna use in this project filament PHP which is a toolkit for laravel Artisans which is tall it's a talent alpine.js laravel and Live Wire that's pretty awesome kit in my opinion right here you can check the admin panel demo as well but we're going to actually install this in our laravel 10 project and configure it and create admin panel with this tall kit if you want to see the final version of The Source Code you can check this on my GitHub the code holy slash laravel 10 block and finally we're going to use the following template that's a very very minimalistic blog template we're going to have only categories and a listing of the blocks and then in your page of the blog we aren't going to have a Authentication or authorization system users would just be able to browse the blog website and just have a look at the Articles and read or filter by category okay so this is the overview now we can already start building our project I'm going to close uh actually let's leave this because we're going to need this I'm going to close my GitHub and we will need this also because we're gonna check the documentation for the filament PHP from time to time now let's open marvel.com and go to the documentation and we're going to set up the project with the docker as I mentioned so I'm going to click getting started on Windows scroll down below right here we have the following command we need to run this in our Linux terminal okay again if you are Mac OS or Linux user you just need to run this in your terminal probably you will already have crl command available if not then you just need to install crl on Windows when you set up wso2 with the Linux operating system in my tutorial I set up with Ubuntu then you're good to go you will have this URL right there okay now let's open Ubuntu here it is and I'm gonna go inside www folder and I'm going to call um well actually we need to paste this crl comment right here right click and let's give it proper name example app is not the proper name we're going to call this laravel 10 new uh well larval 10 blog Dash new okay because I already have a lot of 10 blog so I'm going to call this laravel 10 block new let's hit the enter this will take a lot of time basically if you are running these a very first time on your operating system it will download a lot of things uh it will clone clone the laravel project locally and then it will also download the docker images and set them up and execute them okay so I'm going to pause the recording and get back when this is done it downloaded all the images and at this stage we have to provide our operating system uh root password I'm going to provide my root password for Ubuntu hit the enter and here it is so it successfully installed our project and we need to navigate into the folder and then execute vendor bin sale app okay so let's navigate into laravel obtain blog Dash new and then well actually I can execute this vendor bin sale up from here but first i'm going to open this in my editor or ID I'm going to use phpstorm and basically let's type explorer.xa and Dot so I'm basically trying to open right now the current folder with the Windows Explorer here it was opened on my second screen this is it and I'm going to go inside www here I have all the projects and this is it so level 10 blog new right click on this and open folder is PHP show and approach it okay so it's gonna open in a second if it asks you whether you want to trust that folder and project you just need to click trust it and here it is so the project was opened in from now on I'm not gonna use this Ubuntu terminal instead I'm going to use PHP storms integrated terminal and we have to start the project using sales so now it's indexing it will take a couple of seconds but we can actually already start the project we don't need to wait vendor Bean sale app okay so sales is basically a containerization mechanism built on top of the docker it's a specially created for laravel and it makes a working with Docker very easy okay we just run uh sale app I'm going to open second terminal and now uh we're gonna go inside the container inside the main laravel container and then every Artisan command needs to be run from that container all right so we're going to execute vendor Bean sale Bash and now we are inside that container and now here we have PHP latest version PHP 8.2 and we have Artisan command and everything right here so we are in the HTML folder which has all the files of the live okay so this HTML is mapped to the current directory so so far so good and we have this application up and running right here now let's install filament PHP let's go in the filamentphp.com and scroll down below I want to find the documentation page right here we see the instruction how we're going to include that in the admin panel an example how that actually looks like and in my opinion this looks amazing and let's go in the documentation right here so down below you can also find other packages form Builder and table Builder but we're going to also explore them inside the admin panel documentation which actually actually includes other packages as well so here is the documentation and let's click on the installation because the requirements are there we have the latest version of PHP because we are doing this on Docker we have everything ladies like the latest version of laravel PHP and MySQL as well okay uh it's it's amazing I really love working with Docker because you don't really care what version of PHP you have on your operating system when you are developing on Docker you don't even need to have PHP installed locally on your operating system which is in my opinion amazing okay let's open now PHP storm and we're going to run all the commands as I mentioned from here so installation very easy very first step is to require filament PHP so I'm going to copy that and paste right here hit the enter it's gonna install it then we're gonna open composer Json and put this in the post update CMD so I'm just going to copy that and let's open composer Json and let's search for post update CMD by the way the filament PHP was installed I'm going to collapse this terminal and open whenever I need that okay oops we don't need double quotations okay we need it like this okay filament PHP was was uh fully installed let's check the documentation again and we have added this in the post update CMD as well and now we need to create new filament user before we do this if we open now localhost slash admin that's going to open filament PHP login page okay but at the moment we don't have any users so we won't be able to log in Click right here we don't even have the users table that's that's interesting we need to run migrations let's open um again terminal and let's execute PHP Artisan migrate in the enter okay so for so good now let's if we just click right here the user doesn't exist okay now let's execute PHP artisan make filament Dash user hit the enter let's provide the name let's provide email hit the enter okay right here I'm going to type yes but for some reason it shows an error okay so now the user is already created and if I hit sign in with the user and password I'm inside the filament admin panel okay now we can start working and developing from here but first I think we need to generate migrations and models before we generate migrations and models let's create a storage link because we're gonna upload images and we will need storage to be properly linked I'm going to execute PHP Artisan storage column Link in the enter and the link has been created now let's create two main models one will be article so PHP not article but category PHP artisan make model category and I'm going to specify Dash M as well because I will need migration for this as well let's hit the enter it was generated and the second will be host a model with its migration it was generated as well and I will also need category post which will be Junction table between posts and categories because one category will belong to multiple posts and one post might have multiple categories posts and categories will have many to many relationship I'm going to execute PHP artisan make model category category post okay and the immigration was created excuse me migration was created okay and so we have that and now I think we just need to open the migration files and just write them so let's go in the database migrations and create categories table here it is okay so what Fields do we need right here for categories I'm going to make it very simple and I will just add two columns both of them will be string one will be title let's give it large length and the second will be Slack okay as easy as that now let's open second which is host table this is the main table so we will need much more Fields right here let's define table we will need string which will be title with the same length we will need slag we will need thumbnail as well which will be the main image or the post and we can make thumbnail as nullable it's not actually required we will need body which should be long text and body needs to be required so we just remove this nullable we will also need a one Boolean column which should be active and we will need date time column oops date time which should be published it when the article when the post should be published and become available on the website and probably the last one will be the foreign key to the user so that should be foreign ID 4 we have to specify user model right here class and the field name will be user ID later in this course we can also add meta fields for search engine optimization to post table SEO is key for every website you want your website to be discovered by Google especially your blog website you want your posts to be found whenever people search for something that's why you should try to do your best and Implement best SEO on your website speaking about SEO if you want to know how search engines work check introduction to search engines course at brilliant.org who is kindly sponsoring this video brilliant.org is the best way to learn your desired topics interactively the search engines course at brilliant.org will give you an excellent understanding how search engines work how indices are implemented or how to implement your own search they have courses around math computer science algorithm fundamentals data science neural networks and much much more their lessons are super engaging and interactive I love their algorithm fundamentals course that's a great introduction to very popular and useful algorithms such as binary search or sorting of arrays in this course you will also learn what is Big O notation which is to measure the time complexity of your code to try everything brilliant.org offers 30 days free trial visit brilliant.org the code holy or click the link in the video description first 200 users will get 20 off on their annual subscription the price is very affordable so I really recommend to check brilliant.org the code holic and start learning interactively today okay so we have that generated and I think we need to create also a junction table so let's open now create category posts this should be called in a singular form because that is how it is recommended on the level actually now I'm going to open a lot of documentation page because I always say that whenever you create projects you should have the documentation always open next to you and you should always try to stick with the documentation because in this case uh you will constantly checking the documentation learning constantly as well as preserving best practices because in the documentation you will often find highlighted section for some best practices okay now let's search for many too many right here mean to manual relationships here we have that table structure and this is exactly what I was talking about so we have users or roles and role user okay so roll user table is in a singular form okay and then here's also an example of the modal structure and everything so we need to call our table category post and we will need a foreign IDs to categories as well as to posts so table fouring ID that should be category ID references on ID on table categories okay and we have to specify as well on delete to be cast 8. whenever category is deleted I want a category post records to be deleted as well okay and then we will need post ID here that references ID on table posts and on delete we need Cascade as well whenever post is deleted that Junction table records should also be deleted okay so we have migrations migrations ready and now let's execute PHP Artisan migrate hit enter okay we probably have some kind of error published it now okay so first we'll successfully run second was failed let's check one mistake I have date times that should be daytime should not be date times okay let's clear the console and execute and here we go so that was actually successfully migrated now we have tables created and now let's open category category dot PHP so I want to open category model and I'm gonna add right here fillable so we have title and slack and we're gonna add this inside fillable let's copy this and now let's open post.php model paste this right here so we have a title slug we will need thumbnail everything basically every column so I'm going to open a post table and copy those including user ID and maybe I'm going to delete this paste everything create multi-cursor and do like this here we go so inside fillable I have all the post fields okay and I'm going to Define also relations from category to post and vice versa and inside post we also need relation to users so let's create a public function user we are going to return this belongs to user is that app models user yes it is okay so this belongs to user and let's define the return type as well so that is the relations belong to and I generally don't like so long on namespaces inside the return type so I'm going to just move this up so we will have use right here okay and now let's define um let's define categories so post has categories we're going to return these belongs belongs to many and here I'm going to specify category class okay and let's specify return type here as well okay so post belongs to many categories and we need to do this inversed inside category so I'm going to go in the categories so let's create right here post function return this um this belongs to many host like this okay and let's specify return type as well okay so we have our models and migrations I think fully ready okay now let me close everything and I'm going to open our browser open the website let's move this as a very first Tab and we're going to generate crud for categories and for posts and those cards are called resources if we go in the filament PHP scroll down below right here after uh the user generated right here we have the section link to the section building resources or or on the left side we have this resources section and getting started okay so we need to create resource and when we create resource it generates the following files a resource and Pages as well for create edit and list we can also generate a view page for each resource well actually I think best will be if I generate and then explore that so I'm going to execute PHP artisan make filament Dash resource let's specify category but I'm not going to hit enter so if we have a look in the filament documentation we can generate two types of resources one is normal resource and second is simple resource when we generate simple resource it doesn't have dedicated Pages for create and update instead it uses models so categories is more like a simple resource we don't need dedicated Pages for category view or edit it can be just module because we have only one Field title and the slug is automatically generated from the title okay so for categories we need simple four posts we need full version but we if we want to generate forms in the tables as well then we need to install talktrain debug package which will read the schema and based on the schema it will generate those those form fields and tables as well okay that's pretty interesting so let's actually first Inc include Doctrine and debal if that's not included in composer Json and by default I think it's not included so let's just execute composer require Doctrine debel because we just need this for development only we have to specify Dev right here that's an old error don't pay attention to that okay so here it was installed and now let's execute the following command but first four categories I'm going to specify right here category and we're going to specify as well dash dash simple flag and generate okay in this dish generate will create form and table components as well so let's hit the enter and now let's check admin panel reload the page and it automatically detected and used that categories right here okay so if I click the categories we don't have any categories at the moment but we have full credit functionality I'm going to click new category and call this test for example well slug is not at the moment automatically generated this is something we need to take care of but if I just click create I have the validation error I just type test right here as well and click create okay and we see the record is added we can click edit change we can click delete okay and this is full fully functional uh crot already which is amazing just executing a single line let's do the same thing now for posts but we don't want simple we want full version and we have to specify instead of simple let's specify view as well because we want dedicated view page as well for the Post okay so let's hit the enter so the post resource was generated and if I just reload the page posts are available right here new post and we will have all the fields like titles like thumbnail body and everything is right here okay and we have the user which is uh at the moment drop down but we don't need this right here because we're gonna assign authorized authenticated users okay so now let's check what has been actually generated go in the app let's call UPS everything go in the app filament and right here we have resources and two main resources category resource and post resource and there are also folders with the same name four pages for simple we have manage categories which is responsible this one is responsible for managing the categories and we have dedicated Pages create edit list in The View all right mostly we are going to work inside resources classes okay so now let's open category resource and we're gonna have a look so we have two Fields right here title and slack they are text inputs both of them are required and they also have max length right here and down below we have the table title slot create updated at those fields and we have actions as well edit and delete and we have bulk actions which is delete okay it's pretty awesome now let's have a look in the post resource so we have much more Fields right here title slack all of them not all of them but most of them are text Fields this one is toggle it's actually switch and the doctrine Depot detected that that was a Boolean and it generated switch the filament generated switch for that and we have daytime picker as well right here we can pick the exact time when we want this post to be published on the website and we have select which has relationship to the user and right here we specify which which column I want to be displayed right here that's pretty configurable and really awesome the filament PHP and it's also pretty popular if you check their GitHub you will find like a few thousand stars I think 5 000 Stars right there it's pretty good and that's why it's it's it has so many stars right here I change this field into email just to demonstrate that we can change the relationship column name and just like these is now there is email available but as I mentioned we don't need this user ID right here so we can completely remove it but before I clean up this a little bit I want to First Implement generating slags from the title which is pretty interesting so right here we have the columns and down below we have this actions for posts we have only View and a detections by the way let's add right here delete action as well and we have a bulk daily detection as well so now if I go in the posts and if I just create new test post let's fill on the required fields Okay click create it was created whenever it is created we still stay on the same page this is something which is configurable so we can do that if we don't like and here's the post and we just added delete action right here by adding the following line that delete button is available if we just remove that line we won't see that delete button if we want to delete the post when to go in the edit and then click delete but I think it's really convenient to have this delete right here especially it doesn't delete automatically but it asks this nice confirmation okay I think we we don't need that so we can delete this now let's open category resource and go under title text input field and we have to add uh right here a few few things to uh generate slag based on title and we need to listen to the event after State updated and that's obviously accepts callback because that's an event it accepts callback so we have right here closure set and we accept state as well okay so we can import that closure it's a standard class and then I'm going to call set which is uh closure the set and pass the field name in this case we passed slag and that slug should be at like a title converted into slack so in this case state will be title so I just need to use Str helper to call slag on that and specify state so whenever the state is updated for the title uh alpine.js Live Wire more specifically Live Wire will generate slag and update that so if I save this now and click go in the categories and click new category and just type right here lorem ipsum uh okay it does not work because I missed that we have to specify reactive so this field is reactive okay this is something without that it it doesn't work now let's reload the page and that should be lorem okay so and the slack was automatically generated okay you can change the slack if you don't like and click create uh and when you change this login then if you decide to change the title into something else then slack will be regenerated okay just click create right here and we need to copy this functionality into post Resource as well so let's put this right here okay we have two commas and we need to import closure okay now let's go in the posts click new post and lorem ipsum and this lag is actually generated so perfect now let's adjust the columns of the tables for categories and posts as well as the form input Fields let's open phpstorm and go in the table method and we have title slog created at and updated it I think we don't need slug in this table and maybe created it as well only title and updated it will be enough if I just reload the page we see only those two fields so we can also move these categories into a different section at the moment dashboard categories and posts are all in the same section but we can actually change this if we open this category resource and I believe right here we have this property called navigation group and then we just specify the text for example content I'm going to save this and if I reload the page we see that categories are now under content section in this collapsible section by the way we can also change the icon right here the filament PHP uses a hero icons but version one okay so if we just type in the Google Hero icons and I really love those icons it's very easy to get started and use that you just need to copy SVG in HTML files in this case we need only names but this is version two okay we need to go to the version one here it is and then any name right here can be used after heroicon Dash o instead of collection we can type for example academic cap and just like this we can use any icons available right here which is awesome and we're going to actually change the icon but for the posts let's open post resource and let's change this icon into something like let's search for document Maybe now we have multiple document variations let's use document text I'm going to get this name and paste this right here and now let's use navigation group as well to be the same content so we need uh categories and posts both to be under content section here we go and the icon was also changed for posts now let's open posts and click new post I'm going to work now on this form and adjust the layout change the thumbnail to being a file upload field remove these users basically all the work that is necessary right here and it will also open the filament documentation and what we need is layouts so let's scroll up click on search and we can search for layouts I really like the way how filament PHP gives you possibility to uh configure your layouts okay so if you have a look you we have those columns I think this is for the tables but I want for forms okay I want layouts for forms okay it comes from the okay let's have a look layout yeah that's it here we go so basically all the form is rendered in this category resource right here under form schema method okay so we have those fields we can group them we can reorder them we can split them at the moment it is already split into two columns because by default it is implemented like this but we can actually combine this or we can wrap everything into a card so I'm gonna actually use card at the moment so inside the form we need to use card component that is filament components card make and we have to pass make and then we need schema we pass an array and we can put everything inside the schema so I'm going to actually take everything from here and put this inside the card and let's format the code okay now have everything in the card if I save this and reload the page we see everything now is inside the card and I really like this approach that's that's in my opinion better and I want the for example slug to be on the right side of the title okay in the thumbnail and body and everything to be like like they are at the moment okay so I'm gonna go and make changes right here I'm going to actually use a section component I believe it is section let's actually go in the documentation and search for section also has heading maybe we don't want heading it's called probably something else so we have possibility to generate Wizards or tabs or field sets I think what I need is either grid yeah I think we need grid so I'm going to get the grid paste but I won't The r2b2 Columns okay and actually if I just delete and autocomplete grid okay here we go so I'm going to call make with two columns and then I'm going to call schema on that and put title in slug in site okay so now we have form inside the form we have single card like this inside card we have one grid and then we have Fields okay if I save this in now have a look now I see title and slog next to each other okay this is exactly how I want it so if I start typing now this log is still populated now let's change this thumbnail into file upload so I'm going to use now file upload and we don't need max length and let's have a look here it is and we can have a look in the how many ends did I set okay let's search for fields I want to show you all field options what we have here it is under four Builder section I really like the documentation it's a very well organized uh we are are a where's that here it is so field getting started okay this is where we are at the moment and we have uh many different types like text input select checkbox toggle a radio file upload reach tags reach editor which is we can also use and repeater and Builder and uh here here's everything basically what it supports and you can also have create your own custom custom fields which is pretty cool okay I'm going to change these thumbnail into file upload I already did that I'm going to change this into reach editor that should be toggled and I'm going to remove the user but I'm going to change this into categories okay so relationship goes into categories and the title should be the column name should be title because categories has title column so we're gonna display title right here and this should be categories like this okay and that is required now that's actually not required you can skip categories on the post or or let's let's make it required why why you should create a post without categories not sure now let's reload the page we have an error belongs to many get owner key and name I think that should be it should be category ID no let's specify right here multiple we we need this to be multiple maybe that's that's the point yeah that's it so now inside categories when we start typing something it autocompletes at the moment I think we don't have anything in the categories so I want to actually delete this and create few actual categories like JavaScript let's create PHP let's create alarm l I think three will be now or testing new form and I start typing and it searches and duties so we can specify now multiple categories to our post and that looks pretty cool so I want to re change the layout again and this is also Rich Text pay attention but I want to change the layout and I want like a thumbnail in categories to be on the right side of this form so here we have this card and I'm going to create well we can create another card or we can create a greed and that greed uh can be splitted into how should I do this so let's make this form to have like a column length columns 12 columns okay so the form now has 12 columns this card which is the main card let's give it let's give it calls Pawn column spawn to have eight and I'm going to create now the same type of card second card now and that will have comma is missing here and this will have call spawn four okay and I'm going to take thumbnail and categories inside the sidebar so I format the code save everything reload the page and this is exactly what I wanted so we see right here horizontal scroll because my browser zoomed in uh a lot actually because I'm like generally zooming when I when I'm developing something it's it was even zoomed out but like on a normal screen it will look like this okay you can adjust the layout as much as you need if I click browse and choose some type of image let's choose this one then it is uploaded successfully and if I choose now let's save this actually let's make record so um I have this Auto completed why JavaScript is weird and lorem ipsum okay let's create click create this field is required but that should not be required so I I should have made it optional in migrations I'm going to specify this right now create record user ID doesn't have default value okay so now we need to set the user when the record is about to be created let's open again filament documentation and let's search for creating records creating records and customizing Data before saving this is exactly what we want and we can create we should create the following function I'm going to actually copy this function and go under post resource and create post okay so that is which should have the following method and if I save this now and just close this and hit create again hit create again okay I think because this is required but I actually populate this okay so that was created that was created okay here it is so we have user zura we have created update that basically everything except the thumbnail because the thumbnail needs to be an image okay and I think because we have this is the view Page by the way when we click on the record this is view page I click edit we are in the edit page the image is not properly saved let's choose the image again let's make detective by the way and let's click save changes okay that was saved okay now we have the thumbnail okay perfect now let's let's modify this table because I think we did everything uh pretty well in the uh article post creation page now let's adjust this let's go in the post resource scroll down below I don't want slog I don't want body and do I need username no I think I don't need the username however I'm going to comment this out don't remove and I'm going to remove also uh created it I will leave these published it so I save this and I'm going to make this also to be image column and the active is icon column which is good so I just reload the page let's move this thumbnail as a very first so we have a thumbnail we have titles status published it and updated it okay and just like this we have customized our crud whenever we click on the recording it is selected we have possibility to delete because that is added in the bulk edit bulk actions that's awesome if you are enjoying this video so far make sure you hit the like button thank you now I'm going to create one more post and then we can move on the front end that is lorem ipsum post and I'll specify right here oops to be PHP I'm not going to make it active also I'm not going to choose published it let's type test right here and click create okay we just need to adjust this I'm going to go in the post resource and in the form I'm going to remove required on the publish date however if it is required on the database level we are going to have problems so uh let's just reload the page let's specify Laura ipsum and click create okay category is required so we have to specify it this is required we have to specify it and click create okay publish that can be now that's exactly what I was thinking so actually I prefer to open now my existing migration which is for categories unfortunately I have to like I can create new migration and change the column but I think it will be more relevant to just uh make these nullable right here but in this case I have to drop last two migrations and recreate them so PHP Artisan uh migrate I'll roll back Dash Dash step equals two it will roll back let me create roll back okay is there any kind of error Canon drop table pause referenced by Foreign key constraint Okay so hold on right here I am dropping category posts but that should be category post this is the problem okay so this was problem because when this group migration rollback was run it tried to drop the category posts and then when the second migration was run it tried to draw posts but that post was still referencing to the category post table so let's execute these okay we have problem again drop table if exist pose that references to category post ID foreign okay white is that problem actually so first category post needs to be dropped right so I execute step one I think that was already dropped if we check migrations if we check migrations that's interesting what's going to be the status right there I'm going to use now phpstorms database tool and you can use basically any database client like MySQL workbench for example to connect to the database which is running under Docker so the host is localhost this is the default Port the user will be sale and password is just password literally password like this okay let's test the connection yep it works let me choose the schema schema needs to be okay what's key Mouse do we have there are four schemas laravel 10 block new this is what I want to choose and check now migrations let's have a look what's the latest migration there let's create posts table and it it is trying to drop posts but I think it cannot drop because there are records in the posts okay that is very very edge case because I just uh forgot to add the nullable in the published it so it doesn't work to spend too much time on this I'm going to go in the posts and just delete that and hopefully now I can roll back one no actually it does not roll back why because probably because the table is not dropped category post is not dropped exactly exactly so the previous migration that migration was rolled back because right here it was written right here it was written drop if exists category posts that did not exist the category post table that was not dropped and but this record was removed from the migrations table is successfully rolled back that's that's it so I can manually delete category post okay and now I can roll back yes and now I can run PHP art design me great okay those two migrations will be reapplied now if I check the database I will see category post right here and again I'm going to check uh post table and I will see published it is not required anymore okay it doesn't have that Green Dot next to it which indicates that it is required or not now I'm going to go under hose and I'm going to create why JavaScript is weird again let's choose this keyboard which is not relevant but like we are testing at the moment here it is and let's specify test here and click create okay that was created we haven't specified published yet because we just created our post we don't want it to be published at the moment okay that's the whole idea let's create second post lorem ipsum test let's specify now Mouse and test again right here right here we have possibility to specify headings and subheadings and lists and images as well as the code block which is pretty cool okay let's choose now this to be laravel and click create okay so we have successfully created two posts and I think now we can move on the front and side okay now let's open front end I'm gonna just uh let's duplicate this probably and remove it so this is the front-end side and this is our blog template which we want to either download or grab content so you click this get template it opens the GitHub link and then we have two html's plugin posts I'm going to click on blog and right here we have the whole HTML it uses alpine.js and Talon CSS okay and we need to adjust them okay I'm gonna click on row and get entire HTML okay now let's open uh phpstorm and go let's collapse everything and go under resources and Views at the moment we have only welcome blade which has the layout as well as the content we don't need that uh to be like this I want to create layout so I'm going to create now component PHP artisan make component let's call this up layout hit the enter okay app layout component was created so if we go in under app view components up layout it has right here view named which is under components app layout well I'm going to change these to be layouts up just like this so now if I go in the resources views right here we have components and then app layout I'm going to rename the components folder called this layouts and I'm going to rename this app layout and just call up so that the view name exactly matches now the component layout and I'm going to open now layout which is empty almost empty now it's empty and I'm going to paste entire HTML which I copied from the GitHub okay now let's identify what is actually layout and what is part of The View so this is body we have the navigation we have the header and we have a topic navigation as well and then container comes and then we have the section and then a side and below is a footer okay and some alpine.js scripts so if we have a look in the design so what is the layout obviously this top part is part of layout we can consider this about us and that Instagram section to be part of layout as well or maybe we don't even need that I actually want to put right here latest posts maybe or latest categories right here we don't need obviously this in Instagram section so we can at the moment we can make this part of the layout okay and this will be actually the content so this will be actually content I'm going to get these and because this is layout I'm going to Output right here slot okay now I'm going to open this welcome blade um actually I just copied this portion so I'm going to save it somewhere so I'm going to create new scritch file blade scratch file and paste it okay here we have couple of Articles those are demo articles I don't want this uh to be lost so I have this in scratch file now right here we have to make few changes if I open we'll complete again like the language is taken from the app get local so I need to get that HTML in the layout replace that like oops copy this and replace here okay we also want this is the welcome Inc title so we can use the title from the configs but I think that's okay so we can leave this at the moment talwind blog template uh the content the author content we can remove that okay I think this is this is okay this is good now let's edit uh this welcome delete everything and take those articles from the scratch file and put under welcome okay then I'm going to close the script file and finally I'm going to rename the welcome to be homeblade okay now if we open web.php and change this into home save that and open our application and just reload uh we have problem we don't have styles let's inspect this and have a look reload the page okay I know the reason in the home we don't use the component as a layout so we need to use x up layout like this save and reload and here we go so this is now our laravel application we have layout defined and we have content coming from the home now let's create controller and select posts and pass this to the view and render them properly we don't want anything to be hard-coded right here okay I'm gonna bring up the terminal and create controller by executing PHP artisan make controller and let's call this post controller and let's also specify dash dash resource we don't need everything every resource methods but let's specify still because deleting is much easier than create than writing so resource and dash dash model equals post let's hit the enter post controller created successfully and let's open post controller and we have to work in the index let's actually return view from here which should be home okay and let's open web and I'm going to change this into post controller index and let's give it also a name to be home and let's change this use qualifier with import so I save this reload I see the exact same result now let's open post controller and I'm going to actually close everything else so right here we can by the way specify uh based on the PHP based on the laravel chain and now we can have types everywhere because the minimum PHP requirement for a lot of attain is 8.1 okay we can specify a view for example that should return illuminate View or we can just leave this empty as it is right now that's not going to hurt as well but that's additional like small uh security measurement that make sure that you always return vo and nothing else from from here now we need to query posts all SQL post a specified query and we want to um only select those posts which has active equals one and we want also those which is published so where published it equals null or no where it does not equal now actually or is not null would be more uh more accurate maybe but let's have a look what this will select order by we're gonna order that by published it with descending and I'm going to call paginate on that because we will need pagination as well so we have posts and I'm gonna pass now posts using compact function to view now if I open home.blade PHP right here we need we have three articles okay the structure is identical but we don't need all of them we just need one which we need to put inside the loop but I want to actually create maybe a separate dedicated component or that article PHP artisan make a component let's call this uh post item component okay and I think we don't need a special class for that we can just create view only uh view I believe that's the correct flag component created successfully now let's have a look uh do we have the component under up view components now we don't have if we go under resources views components we have post item right here okay and now I'm gonna copy this article and paste into post item and we're going to accept right here post and then based on the post we are going to Output certain information but from here we are gonna iterate over posts is post and then we're going to call X post item like this and we specify post that's going to be the post like this we need to accept that uh post right here let's Implement actually outputting post item right here in this component so we already have post variable available right here so let's just try to Output right here thumbnail for example post thumbnail then right here we need to Output categories so I'm going to start iterating over categories for the Post we will need post categories is a category and like this let's output right here category title and right here we need to link to that page where we will see only those posts which belong to the category so we don't have that road created yet so I'm going to leave these as it is right now so this one will be title for the Post because this is a post item so this should not be an a um excuse me so this should be an a actually and this should be linked uh to the inner page of the post we don't also have that road we're going to create that so let's output right here post title at the moment and down below we have the user so we can have uh post like this host user name and published on Android here we need date okay so here we should have post published it and down below we need to Output the description the content not the whole content should be outputed right here so it will make sense if we just output short like a few few symbols not not the whole body so maybe let's assume that we create a special method in the post model like um get or just short body okay so post has buddy but we don't want the whole body to be outputted in the listing so let's just call short body and we will have to create that method in the in the post but for now let's save this and have a look in the browser here we go so let's just click on this roll the page okay nothing is actually selected and let's go in the post controller because I think we have something Okay so this wear should be probably changed into a weird date because we have that to be date and then published it must be published it actually must be um less than now and we should use carbon now okay so published it needs to be uh in the past basically so if I save this and now rule of the page we don't see anything now let's check our posts and yeah the active status is not marked so we just click on edit and let's mark this active and let's choose date which is in the past okay so that was saved and let's activate the second one that is in the past perfect now let's reload the page okay so we have an error which is good the short body doesn't exist now let's open host here we have the post model and we have control and click on that and now let's create that short body now we should return string and we are going to return from here Str words I think I'm using different Str uh return Str which should be illuminate illuminate support then we're going to call words method and that then I'm going to strip strip tags remove basically any tags from this body and then finally I'm going to just output like a 30 words from this um from this body so if I save this now and reload the page we see post is actually rendered the description is not there because the description actually is not written inside so let me actually generate lorem ipsum text if I go in any blade file and just type lore m and hit the tab this is it okay so I'm going to cut this and then I'm going to basically delete everything and paste oops okay let me remove any kind of formatting paste this right here and I'm going to paste multiple paragraphs okay so this is just just lowering me some text so I say that was lowering up some tests and now if I just reload so here we see that the title is not outputted for some reason where is the Post item oops I have a typo lowering some test and as you see we see like a short description of the long and that's pretty cool if the description is too small then the card is displayed like this that's a Talon CSS like a ping and we can fix that using title and CSS but in most cases in 99 persons the descriptions will always be at least one line so if the description is like long enough then this card will be on full width but of course like we can add some tolerances classes to stretch the Turn full width what I don't like is the date how this looks like so let's create actually a function like git a formatted date something like this and let's open now this post and create formatted data we're going to return this published it in the published it actually needs to be an instance of carbon by default published it will be I think it will be string um actually that's good point to actually see what's published at so this published it okay now let's see what's published it that's a string as I mentioned but if we create a protected variable costs right here and specify that published it I want this to be like date time then this will be an instance of carbon so if I say this and Rule of the page now we see that this is an instance of carbon okay and on this date time right here I can call method like format and specify the format so I want the format to be F oh let's put in the string F then J uppercase s and Y so you will see what's the formats and I'm going to just uh reload the page so here we see so J is the name of the math then we have sorry f is the name of the math then we have J which is the number day of the month and then we have this uppercase s which is the um this Rd or first if it's a one it's going to be St if it's 2 it's going to be in D I think it's called ordinal index mature so if we just search for like PHP date time format you will see the actual name of what is this like uppercase s somewhere right here I'm just curious here it is ordinal suffix exactly okay so that's uppercases and if you want to like change the formatting you can find all the formats possible forms right here so I'm going to close this okay now we have dates uh now have user and we have the listing actually the category is actually also correctly outputted however the image is not correctly outputted and if we inspect the image to see what's the path and we see right here that we don't have like um this is localhost Slash the file name so probably storage is missing right there so if I go in the thumbnail input slash storage save and just reload here we go so we have now we have now images available so I think that's pretty cool now we can think this is pretty cool now I think we can move on the pagination to actually activate the pagination we need more than two items two posts I'm gonna go ahead and create all the posts and see that I'm gonna use a cedar for this let's bring up the terminal and I'm going to execute PHP artisan make I'm going to create Factory that's going to post Factory see the internal is open post Factory here it goes and we have to define the definitions for the fields for each field so we have title which is going to be like a fake title so actually I'm going to create a variable right here title which will be like fake uh real real text and we can specify this real text the length of the text as well like 50 for example let's specify so we need title right here we also need the slack which needs to be generated from the title that's why I created title as a variable so I'm going to use the Str slag method for this passing title we will need thumbnail thumb up nail which is going to be image URL we will need body make real text and in the real text we can specify like a large number or Max characters we need active which needs to be Boolean and we have published excuse me published it which needs to be a random date time okay like this and user ID let's specify at the moment user wants so basically every uh post created by this Factory will belong to the user one now let's open a data base Cedar and let's uncomment this Factory and change this into post and we want to create like a 50 posts using this database seater so PHP Artisan DB colon seed let's hit the enter setting database it was finished now let's reload the page and we have those posts created which is fantastic the images are broken because every image now has a slash storage before that okay so I guess that's okay for now because we just uh like fake created the post and the URL basically is an absolute URL from the uh placeholder via placeholder.com so in our application we won't have that like the absolute URLs but it's going to be good addition into the system if we create a function right here which will check if the URL starts with HTTP then it's going to return different thing otherwise it's going to return different things so basically I'm going to use Str hearts excuse me what I'm doing stupid mistake so get get thumbnail maybe so inside get thumbnail I'm going to check if Str come on starts with I'm going to specify if this thumbnail if that starts with http then I'm going to return this thumbnail okay let's put semicolon otherwise we are going to return slash storage slash company so I save this and now all the images should be rendered properly okay we have this one this one but the others are not rendered now let's check what's going on okay that storage is still aided if Str starts with so if the thumbnail starts with http it's gonna return this thumbnail excuse me I don't use this gate terminal so I I generally make such type of mistakes very often so I create that everything looks good I'm surprised why it doesn't work stupid mistake we don't use that it thumbnail here we go load the page Okay okay something is wrong now it's broken for everything storage so we have storage twice I think they should be removed that's it that's more like it no it's not more like it yeah the other images are there but our actual images are not there why because I don't concatenate this with these another stupid mistake no this uh okay challenge do you know what will happen if I leave this code like this just think for five seconds pause the video think for five seconds and just let me know let me know in the comment section down below what was your thoughts but that's gonna definitely cause the uh rushing our browser server because we are calling git thumbnail inside get thumbnail and just like this we will crush it it's basically a recursive function without base case Okay so we're gonna use this get thumbnail now if I reload the page we see the images there okay so now we have more than enough post items to implement actually a G nation so let's go in the post controller and I'm going to set the page Niche 18 to 5. so to make the scrolling easier and now let's go in the home and we have this hard-coded pagination links and at the top of that we are going to Output post links the post basically is a variable which is a paginator variable instance of the paginator and then links will simply render hosts excuse me posts links links will will render the pagination buttons as you see right here okay but we need to adjust these pagination buttons try to create the same design as we have down below okay and we just need to publish the paginator views and modify it so if I open now laravel documentation laravel go in the documentation and search for agination then let's search for publish here we go so under Section like customizing The pagination View we can publish the lateral pagination views and then we can customize that okay so I'm going to copy this command open the terminal and paste this and hit the enter so it's actually published the pagination assets and we can find this under resources views vendor pagination so let's go under resources views vendor pagination in this idea we have different versions for pagination like bootstrap four five some semantic UI Etc so what we are interested is the tile wind blade because this is the default one which is used to just test it if this is the actual one I'm going to delete everything say that and reload the website and we won't see this pagination anymore okay so let's undo this and now let's actually tweak this we have to make few changes right here let's have a look in the home so we have the following classes for the pagination item which is actually active so this one is indicate indicates that the item is active so let's actually copy this open our Talent blade and find the if statement which indicates which one is actually active so I think this is for the mobile and this is for desktop okay let's focus on the desktop fully so here we have this is showing how many items we're going to have so this let's roll over the page so it's showing so we don't actually have this in our design so let's actually remove it I'm going to remove the showing now if the paginator is on the first page then we render the previous we're going to take care of these a little bit later in this case we have this previous URL uh okay where is that that's for three dot separator which we I think also don't need but let's scroll down below here it is so if the page is current page then these are the classes we are going to add so I'm gonna now paste this save and have a look okay this is it okay that looks exactly as this one now let's create styles for the second one now let's go in home this is for the second I think we need to add these classes right here here we go I'm going to paste this or reload the page okay that's good there's also Shadow on this I'm going to remove that shadow where's that shadow this is for next Shadow will be right here on the span okay now we don't have shadows we have a horror effect now let's implement the next button so scroll down below if paginator has more pages then this is for the next one otherwise this is probably next but it's going to be disabled so we don't show disable the next pattern instead we can remove that but if there's more pages we need to show this next and let's take classes for the next one here are the classes I'm going to paste that and also let's take this font awesome icon this one for the next one let's remove this SVG and paste the font awesome icon I'm going to save that reload the page and this is the next icon let's specify by the way text as well next okay perfect so we have imagination links and the next button and when we click on the next button it actually changes into page two now let's Implement previews in the same way in the exact same way so basically I can copy this and find where's the previous that should be at the top right here probably if paginator is on the first page then we show disabled previous which we don't need so I'm going to actually change this if the page editor is not on the first page and delete that and else statement and this is where we're going to display the previews so I'm going to paste my copied anchor link okay let's format the code so we need to change the url to be previous let's remove this let's first display the arrow but the arrow should not be right it should be left and then let's write priv right here and also right here there is a margin left 2 which should be changed into margin right two and right here we also have margin left I'm going to replace this in margin right so I save that reload the page and C here we go so we have previous next and every link if I click previous once again we are on the first page and we don't see previous anymore this is exactly how we want it if I go next next that works now click on the last one and then we don't see next anymore okay perfect if I go in the home right now by the way how the pagination looks like on the yeah so this is how it looks like on mobile so we don't even need these previews and next and we can leave the same thing uh for um or mobile as well so let me actually remove that we don't need open tilewind scroll up that should be should not be hidden so I'm going to remove that it should be Flex always and let's remove this above which is only for mobile save reload the page here we see however it makes sense why larval has different type of pagination on mobile simply because this doesn't look good on mobile isn't is it an actual Mobile screen let's check this let's switch to iPhone that's fine but if there are more than like seven pages then this will look bad let's go in the pagination and change this into two okay displays these three dots right there and there are a lot of positions so actually let's go in the talent and do this we need this on mobile and we can leave that as it is right now and let's undo this CSS class as well so on pagination it will be like it was before that next and previous pythons will be there you get the idea you can customize those buttons If you don't like but that's fine okay I'm going to remove because there are too many links in my opinion so let's go under home and before calling links I'm going to call uh actually that's good point so I want to show you something so if I just debug the posts and have a look so this is an instance of length aware paginator so I'm going to copy that class name maybe the fully qualified name and I'm going to Define right here I'm going to annotate that variable so like this so variable of posts is an instance of this length aware paginator okay now if I try to use posts and call some methods uh PHP stream autocompletes everything what is available there okay uh I think on each side on each side exactly this is what I want so I'm going to set on each side to be one if I save this now and reload the page scroll down below now we have a one on each side of the active menu item okay and that makes more sense so we we learned how we can actually customize these on each side that's pretty cool now let's go in the post controller and I'm going to change this into 10 I'm going to display 10 items per page and since we have implemented now listing of the uh posts we're going to do a couple of things so I'm going to clean up the layout I don't need these images right here Instagram section can be removed we need the About Us section I'm going to leave that I'm going to also clean up the footer basically I'm going to prepare everything as it should be finally and we're going to also make this about text like content to be editable from the admin side and also the um about us page should be also created so let's go let's remove this we don't see any items that's that's fine now let's go in the uh up blade and let's clean up a few things if we start from the top we have this top bar which can be removed that's fine we have minimal blog I'm going to actually call this the code holic blog let's say this this is Laura mipsum text which is like a main sentence about what you want to tell your readers okay so this is something which should be configurable from the admin side let's remove the Instagram section here we go so let's remove it and in the footer there's this Carousel so we can remove this Carousel and this script tag for the carousel data as well okay let's zoom out to have a overall look okay not too bad not too bad okay and down below let's remove the links from the footer as well we don't need that this is myblog.com let's leave it and instead of padding bottom we're going to have padding y vertical okay perfect nice now let's make those texts editable I'm going to actually create a new table for that PHP artisan make model text widget and dash M for immigration as well create text widget table and let's specify a few things right here like we need image and title so let's define table string image that should be like 2000 48 that can be nullable let's duplicate this two times we need titone which can also be nullable so I'm going to make everything nullable and I'm going to explain why I do this and contents well I think we can make title required that's okay and the content needs to be long text and it must definitely be knowledgeable and let's specify also active which needs to be Boolean like this and that by default will be false so now we have this table ready I'm going to add one additional column it's going to be key tring e and that must be required and that must be unique as well so basically the idea is that that's going to be a universal table for saving some text contents for your website like we're going to create About Us section for example the key will be about us and you can specify image or title and content and then based on that this is extra based on that we can select the data from the database and output in certain places in our website so that's that's good we have this text widget ready let's we don't have actually ready we just create migration PHP Artisan migrate and that was applied now let's open text widget and I'm going to Define right here few helper methods first let's define a fillable properties like e let's let me copy everything all of them are fillable like this okay next let's define a public static function git title and this will accept string e and this should return the it should select text widget based on the key and then just a return the value of the title so we are going to query widget which will be text widget query where key equals given key and we have to also specify active status where active corresponds to 1. or true and we're going to call First on this so we're just going to grab the text widget and let's check now if the widget was selected then I'm going to return a widget title otherwise I'm going to return an empty string like this so let's try now to create uh no let me first actually duplicate this let's prepare everything right here so I'm going to duplicate this and create second function get content which is doing something similar but we actually also need probably two add caching I'm going to do also caching but first let's select text widget based on the key and active and then if the widget is found we are going to return content otherwise we're going to return an empty string okay and we might call like we might select one widget and we want both title and content from the widget so if we do like these then this method will be executed and this method will be executed also and this will cause selecting text widgets the same text we just twice why don't we cache our selected text widget so if we need to select it second time it's going to serve from the cache okay that's I think really good optimization point so let's use now cache uh which cache is that illuminate support for size cache then we are gonna call get we need to specify some kind of key like text to widget for example Dash in the text widget key so that's going to be based on that key it will either get it from the cache or select then we have function let's use uh key right here and we are going to return these parts okay and finally we're going to assign this into widget so what this will do is try to get the content from the cache using that key if the content didn't exist then it will execute that function that function will just uh run the following code it will return the value and the cache component cache facade then we'll set that into into cash as well I think it should have get get or said or something like this so we're going to test this as I remember it will simply return that but we can test this so if we're going to get also we don't see that okay I'm sure we can figure this out a little bit later but I just want to mention that when you're developing something if you think putting a little bit extra effort beforehand and then you can finally have a much better product for example you don't select your the same objects twice in the code we can figure this out working also debug this but a little bit later okay so we can do the same thing right here so I'm going to just simply get this and remove that excuse me delete that return this and we're gonna assign this into widget okay perfect now let's generate filament resource for the tech switches PHP art design make element Dash resource let's specify text or widget a resource generate let's see the enter text widget resource was generated now let's check the admin panel we have text switches and that's perfect that's super cool uh let's modify text widget resource text text widget resource let's change the group navigation group to be content we have key which must be required we have image which must be file upload uh we have title which must be required we have content and active in the table we can have just key pain title we don't need in status maybe an updated okay we just need more than expected so and let's actually change this to show inside the form everything in a single column like columns one like this now let's specify about us sidebar for example as a key and then let's choose some sort of image do we need image on the about a sidebar no we don't need that let's specify title about us for example and content which is this well it's a lorem ipsum but you can type about me so I am um developer with 11 plus years of experience that's it okay let's make it active and I'm gonna create that and when this is created I want it to be redirected to the listing page so I will go into text widget resource create text widget and just override the function which I think I did in the posts uh no I haven't done this in the posts uh get redirect URL where do they do it I think I haven't done this okay let's check these filaments uh redirect customizing form redirects here we have this gate redirect URL I'm going to copy that and paste in the text widget resource now we need create text resource paste this right here save that call in the filament I think we need to do the same thing in update 80 text resource so now if I edit these and click save I'm redirected to the list which is exactly what I want to do I actually don't need the view page probably don't need view page so if I go in the list text widgets or maybe view text we just completely delete that and go in the text which is resource and remove this View what will happen text widgets is included somewhere let's remove it okay now it opens edit page which is exactly what I want okay now let's go in the website and we need to Output this about us text widget right here so let's open sidebar uh Side Bar we don't have sidebars so let's create this let's go in the home blade and we render our section right here okay where's the sidebar that is probably in the up blade here we go so this is a side which in my opinion should be that in my opinion should be inside the view so I'm going to take this out and go in the home we have this section which comes right here and then below that section I will put the sidebar so the result is identical and now I'm going to make this as a separate component PHP artisan make component sidebar okay well let's see the inter sidebar component was created cyber blade and now let's get the aside and paste it here and now let's output text widget get title and specify about us sidebar which is the key okay so then I'm going to copy this and right here I'm gonna output it as an HTML but I'm going to specify instead of gate title I'm going to specify get content let's change this into let's leave this by the way we will have to change this whenever the URL is created but let's leave it as it is for now and let's have a look if we go in the home blade we need to use x sidebar component and here we go so we have this about us which comes from the back end okay now we have a possibility to fully customize that text specify whatever you want as well as change the title uh save that reload here we go that view button by the way needs to be removed so if we simply go in the edit text and view remove reload that's perfect okay now in the same way let's create a new text widget for the following text new widget header let's call it just header header and the content will be something you know I'm going to just copy and paste this I don't want to spend time on come up something so that's active let's click create reload the page of course we haven't used that up blade and at the very top we have this lorem ipsum something so we will output text widget get get content that's going to be Laura mips or something actually this one will have a paragraph inside so what we can do is just output the header this is this is a title and we can output the title in this case the title should be this one let me change this leave the content so the content basically is more for HTML content and by the way I haven't changed this into Rich Text which I should have done let's change this into here it is reach reach text reach editor so this content is more for reach editor and I'm going to specify this loading with some here and if I go in the layout now I want to Output the title for header save reload we see the same thing if I modify this we see now modify text so that shows and this shows that it actually works perfectly so these text widgets are basically really handy in certain cases so you have key and you can select uh the text which is managed from the admin panel in any place you want in the same fashion we're going to create a little bit later about page where we will create a new text widget for the about and we'll output that so I think that's perfect now let's start working on the post in your page let's open web.php and create new roots that will be simply post right here but we have to specify that I want to select the post by Slack and we're going to have show and it's going to be View what's going to show we already accept posts right here but that post might not be active so we have to make an additional checks like if post is not active or if post published it is in the future to specify carbon now if that happens then let's just throw new not found HTTP exception this one okay otherwise we're going to proceed and return View show and we have compact here and we need to select actually post no we don't need we have post so I'll just specify post here okay perfect let's also have a look at the blog template we are using and we have to just copy the blog in your page Post in your page content before that let's create this blade file and the resources we use let's actually create well that should be post dot show or maybe post start View so under views let's create new file post slash View Dot blade.php perfect we need to use x app layout and now let's open our blog template here it is Click get template click on post HTML and click on enroll so this is the HTML we need I'm going to copy everything but we don't need to have a layout so I'm going to paste it and then clean up so we don't need this HTML and talk type because we already have layout defined but we don't need the stop nav bar we don't need this one and the only thing what we need is this post section so everything above can be deleted and everything below can be deleted as well like this so let's format the code I'm going to save these and reload the page and we actually have to make proper links so I'm going to open post item blade and let's specify now proper links so here we need Road View and we have to specify an actual post let's copy this when we click on the image this is just for the categories when we click on the title we want to open the view page and when we click on the body we want it to open a view page as well so I save that reload the page and let's click on the image you see so it opens the view page and this is a slug we have an image this is what's the images done yeah everything is dummy yeah I bet so everything is done right here we have to make it uh active coming from the database and we have to also implement this previous in the next buttons that's also very interesting and I'm going to remove this user card at the moment I don't need that let's go in the view blade let's expand this and let's now output the image let me actually get this from here so this is an image paste I will need I will need categories as well so I'm going to copy that and paste here I will need titles yeah title as well um we need to drink a water like I'm talking uh one hour Non-Stop and my my voice changes actually so we have this categories let's format these and this is the actual post title so I'm gonna get that well we need just post title we don't need this to be an anchor link because that's that's not necessary we are in the post in your page so I'm going to change this into H1 remove this href and have both Title Here and then we have the user information and the publish date let's copy this get formatted date as well right here and let's get this username okay so everything below is already part of the body so I'm gonna delete that I'm going to delete that and I'm going to Output post buddy so let's wrap this in a div then we need post body so we save that and have a look so we have an actual image title tag and this is an HTML so we have to Output it differently like this perfect that's pretty cool let's remove the user card this is the user card let's remove it and we have to implement next and previous buttons so we have to do this from the post controller we already have that post selected by larval itself so now let's select next item which will be post query we have to specify that we want only active by the way if I just specify here um true will it work we're gonna see uh we are date published it is less than or equal to carbon carbon now let's specify also okay let me think so we have the post if we have a look so this is let's say this is the very first post and posts are generally sorted by published descending so I want the next basically should query um host which is the first post among those which has published date less than the current post so we have to also specify where weird date like published it is less than less than the current post published it I think this is it and let's order by published it underscore descending and let's limit this into one because I only want to get one and then I'm going to call First on this so we have next uh let's double check this so I want to query active post which has date Which is less than or equal to now which means that it must be published and it's published date is less than the published date of the current post I think that's logical and we order this by the descending date which makes sure that this is the very first among those posts which has published at less than the post date okay I'm going to duplicate this and create call these previews in this case we need to change this less than into greater than and I think everything else stays the same we have to provide here we've and next variables now if I go in The View we have those two anchor tags this is previous and let's let's specify right here title for previous title like this and when to also handle the case when the previous doesn't exist we're going to do that but first I want to see an error for that so here we need next title perfect and if I if I want those links to work as well I have to provide right here Road that's going to be View and I'm going to specify previews and right here wrote View next we save that reload the page and we have an error the error is exactly I believe right here that the previous doesn't exist missing required parameter for roads yeah previous doesn't exist so I'm going to add an extra if statement here if previews exists then we just render it like this however this gives us the next is not on the right side it is on the left side so what I'm gonna do is create two div elements class width one over two and duplicate these this one should be here and the other one should be here oops hold on like this so I'm sure that there will always be two div elements rendered and then inside there there should be anchor links with display block and with the full I save and reload and I see next on the right side if I click on the next it opens the next post and now I should see both previews and next well this doesn't look really nice so probably we need to use here is to your helper and just restrict this into number of words like 10 maybe that's too much maybe like five five words okay not too bad we can even increase this into six six parts um no it should be five okay not bad so I'm going to click next right here and that opens the next one next and now let's go into previous okay something but it happened so when I click next two times and then I click reviews it opens the very first one which is not very accurate if I double check the logic again I think this should be achievous ending that should be ascending if I reload click next once twice and now I click previews it opens the previews and another one is Javascript is weird okay so we have actually implemented the inner page for the Post and we have implemented next in previous buttons and I think we can move on the next section now let's Implement outputting categories in the sidebar and in the main navigation as well so in the main navigation I'm going to Output top five categories by its number of posts inside that category okay and in the sidebar we're going to Simply show all the categories what is available right there but first let's make sure we have the sidebar on the post in your page so if I go in The View and then we have the section let's let's create the very bottom and we are going to display X sidebar component right here so if I save this reload we have this about us so I'm going to display inside the sidebar all the categories okay so here we have that let's define right here I'm going to create this same type of div and then inside there I'm going to create a H3 and let's specify text Excel and we need font semi bold and we need margin button three so let's do like this and that will be all categories then I'm going to iterate categories but I don't have any categories available in this this component sidebar component so let's open sidebar component and first we have to select those categories okay so I'm going to create sidebar um sorry categories equals and I'm going to copy and paste the query and explain then okay so let's import this category so we are curing from a category We join this into category post and we're we're using the proper column names categories ID cost category post category ID then we select categories title categories slag and we also query count um count of everything as a total and we grew by that by categories and order by those total so this will query top five categories sorted by number of hosts inside that category that's pretty cool right so now we use compact in pass categories here and if I go in this sidebar I have categories available so I can already iterate for each categories is category and then we just need to display anchor tag probably href and this is something we need to create that wrote posts by category but then inside there we need category title and let's also specify some tolerances classes like text is semi-bold we need it to be block adding Y2 pining Geeks three maybe and a little bit rounded okay let's make it like this and if I reload the page we see all categories right here okay I think this looks this looks good if I go in the categories we have JavaScript PHP and laravel so that that doesn't show the category which does not have any items inside there and actually I want to also display right here category total because that total is also available because that is selected inside there so I save that reload now we see how many items are in each category and if I change this join into left join then we're gonna also have a look in the yeah let's range one of the categories we are missing but the why was that missing with the join so that should be left joined for sure okay we have now three categories and I'm going to open the post generated active posts by the database Cedar and I'm gonna assign couple of them some actual categories for example let's move this into JavaScript let's open another one move this into JavaScript now if I reload the page I see there are three articles in JavaScript category okay and just like this we'll have all categories on the right side and when we Implement a post Page by category and when we click on this it's going to open that page now let's take care of the header as well in very very similar way so I'm going to open up layout app layout and right here we will need to query categories and by the way this limit 5 is not necessary that query is uh for app layout so I'm going to remove this limit five go in the Apple layout and I'm going to just paste this categories equals that and then we provide compact categories here okay we need top five categories here not inside sidebar okay if we open up blade this is the menu so we have to iterate over categories is category let's move this up and we are gonna output a category title perfect let's add two more pages right here one will be home right here we're going to have home and let's adjust the URL to be wrote or home and second will be about us and that's gonna also have a road uh but let's leave it at the moment because the road doesn't exist yet so I save this reload the page and if any variable categories Double C is not necessary here we go so we have a home page we have JavaScript PHP lateral all the categories what we have uh let me actually quickly change the hover color PG array 400 let's change this into PG like a blue 600 and maybe over text white as well okay much better so we have now main navigation ready when we click on the home that actually works we have to implement now buy category page and Implement also clicking on that on the right side and activate the uh activate all categories actual category which is clicked that's pretty interesting now let's go in the post controller and we have many actions we don't need them I'm going to delete them all of them actually and let's create public function by category here it will accept category and then we need to query posts based on that category let's open web.php as well and duplicate this and I'm going to specify category slash category by slug so we're going to keyword it by category and the view name will be by category as well now let's open this by category and I'm going to again copy and paste the query and I'm going to explain what this query is actually doing so we query posts but we enjoy the post into a junction table category post we are the posts ID equals to the category post post ID then we write it where we are category post category ID is the given category ID we also make sure that the post needs to be active and the published date needs to be in the past and we order everything by publish date one small change we're gonna what I'm going to make in the up layout is that when I join this into like category posts and I order by order by total I don't consider that the post needs to be active and it needs to be published so this query will also get the posts which are not active or not published the same thing will happen in the sidebar okay so just to make sure that I'm correct I will go in the posts open the one which is not active and the sign by the way when I click on the post I want it to start editing so I'm going to go in the post resource and maybe in the post resource and I'm going to remove this view I don't need that list posts edit posts view action remove that hand view action remove let's have a look uh view post is used somewhere get pages okay now click on this it opens edit which is exactly what I want so now let's assign PHP for example save that it is not active pay attention and if I go and just reload the page the count does not increase uh-huh but it should be increased why for JavaScript it is actually increased but not for PHP okay what other are there any other posts that has a PHP there I think there are no posts that has PHP there so let's try to get the one another one so I need to PHP category reload the page now there are two uh two items and pay attention that this is not active so it should not be two it should be one so let me show you remove this PHP because I it seemed to me like there were no posts in the PHP category but it still was showing one exactly so this still is showing one however this obviously shows one because it it should show one that's actually correct if we go in the sidebar we select total count of total everything and that everything includes the category itself okay so this is something which is kind of buggy and we should probably adjust okay I'm going to get back to this um it is this is not accurate hundred percent but as I mentioned um I'm going to get back to this okay so for now let's let's actually implement when we click on the category it should open the post by category so if I go in the sidebar and change these and specify Road to be by category and we have to specify category right here below the page and I click on JavaScript and let's see what happened okay we see an empty page we go in the post controller we don't return anything so we are going to return View what will you should we return should we return the same view like home and maybe provide posts like this okay so we only see one two three one two three we only see three items and again count is not 100 accurate we're gonna fix that but I think filtering by category successfully works so if I click on PHP we have to link this in the header if I click on PHP there are no posts or click on laravel there's actually one post uh that's that's good that's good however I don't want posts to be displayed in header if there are no items there so if I go in the app layout change this left join into just join PHP should disappear I select category join on category post there should not be any record right there it's range well I will try now to print an actual query because I have a feeling something is not exactly as I want so here we have the query and let's dump and die Yuri uh well I need query uh 2sql here we go select from categories uh okay let me carry everything I'm going to open now PHP storms console paste that limit five so we select from categories and we join onto category post finally we have group buy and order by so if I execute that we see PHP okay what is the ID or PHP so I need to query categories ID as well that is five now let's open category post and see if there are any posts for category five actually there is post four four category five which is actually correct so it looks like the count works fine if I edit there's laravel if I edit there's JavaScript and it looks like here it is so we have PHP if I remove that and Save and now let's open code layout remove the stamp and die and now now what happens I removed PHP was it actually removed maybe even no maybe not think it is not deleted that's the main problem stays there again if I reload the page PHP is there I'm going to remove that and save changes huh this is required and that's why I thought the changes were saved but it wasn't saved I'm going to assign it into JavaScript and save that was now saved reload the page let's actually remove this reload and now PHP disappeared from here however it is still available right here which is something we have to fix we have to fix maybe we even completely remove the categories if there are no articles right there it doesn't make any sense to have categories if there are no articles right there so I'm gonna go in the sidebar and change this into join as well we display all categories but if there are no posts in the category we don't display it perfect I liked it now let's go in the app layout and let's adjust the categories right here so that should be wrote by Dash category specify category like this Okay click on these Works click on this works so far so good let's Implement activating the page which is clicked at the moment the category on the sidebar which on which you have clicked so if we go in the sidebar here we go so let's move this class down and I'm going to get call now request and I'm going to get the category and if the category slog equals that request category will be an instance of the category model so if that's log equals is the same as category slag then we're going to mark this item is like highlighted so let's give it BG blue uh 600 and text White otherwise let's give it an empty class let's move this down like this reload the page and now laravel is active I click on the second one and JavaScript is active okay perfect so we made that active and in the same way we can also activate the home in JavaScript about us I will leave this challenge to you now let's Implement a botas page I'm going to open web.php and create a new road that should be above this post slide because that's a very generic route and that will handle everything if there are no more specific roads above that so that should be about Dash as page let's remove it it's going to be pretty straightforward well we can use the same post controller or create new controller I don't know which one will be better maybe creating a new controller PHP artisan make controller site controller enter I'm going to use right here side controller like this and then we're going to have about and the name will be about about Dash us probably so open site controller create that function about and we're going to create text widget to Output the whole content for about that so if I go in the text we just click now let's give it key about page and let's upload also an image some some type of image about us title about us and there's going to be some lorem ipsum long text okay let me make sure they copy anything there's a large text here we go so it also has this code formatting thing so I'm going to make this active and I'm gonna just click create that was created about page and I'm going to go in the about action and we're gonna select the widget so widget equals text text widget Yuri where active equals true and we're going to query first okay if the widget doesn't exist if no widget then there are two options either we can throw not found or we can just assume that everything is empty but I think not found will be more logical in this case Pro new not found HTTP exception otherwise we're going to return View about and provide widget let's actually specify the return type to review illuminate View and let's go under resources and we can create new tweak file about blade.php okay we need X up layout and inside there let's just um let's just use this same type of format we have for the Post page so let's get this section paste it right here then for the image we're gonna use widget widget image and use slash storage slash widget image we don't need the categories section I'm going to remove that we can use widget title we don't need that section or the um get formatted date and we need widget content like this and we don't need this previews and next buttons as well so I save and reload the page let's actually let's open about Dash us here we go um let's remove this width okay it is under container in normal width and the image is broken Y is the image broken because there are no widget image why because I don't have any idea let's check the let's check the text widgets and image we have that image for about page okay then white is not visible okay let's print the whole widget this is widget and it has attributes and it has image to be null because that is about us sidebar because we don't specify key that's the most important thing we just query the first active one but we want to specify key because that is that is essential here the column key equals page save and reload let's go under about and remove this and this is it the image is huge so we have to probably specify Max W full something like this or maybe just W full what is that well it's it shows on a very large width and white does this happen if we quickly inspect that we'll have this section which has correct width and then the article so that article probably needs to have W full that's fine okay if I zoom out this is how it looks like so this is this is a code now let's fix this small bug when we open home page right here we get request category but that request category does not exist and we try to get slack from there that's why we have this error let's go in the sidebar sidebar blade and find this place request category eliminated question mark right here okay so this basically is a relatively new feature it's going to check if the request category exists it's going to take then slack from there if it doesn't exist then it will assume that it is now so if I save that and reload the page the error basically disappears but none of the categories are selected as soon as I click on JavaScript then the JavaScript is selected I click on laravel and laravel is selected it's as easy as that now let's start working on the SEO side search engine optimization is very very important thing for any website especially blog you want your articles to be discovered by Google that's why it's good practice to Define your tags H1 tag meta tags properly and we'll we'll try right now to do this properly every Post in from our admin panel needs to have some type of meta title in meta description fields and this is exactly what we're going to do right now now let's open page perform and terminal and let's go inside the container vendor being sale bash and I'm going to define a new migration file and 82 Fields meet a title and meter description PHP artisan make migration fields to posts table I made few typos two posts table and hit the enter okay let's open now add Nita fields to post table and right here table string let's call this meter title and the length of the field should be like the recommended size for meter title is about 60 characters let's just Define into 155 because this is bar chart and it doesn't hurt so and these must be nullable because if user doesn't want to Define meta title right there we shouldn't force it let's duplicate these and I'm going to Define now meta description okay so we have those two Fields those are two the most important Fields like previously meta keywords were also important but recently uh basically search engines uh updated their strategy how they are searching and meta tiles meta keywords are not that important so we can just get that and I'm going to paste in the down and just change the string into drop column and let's just remove this nullable from there as well and I think this length is not necessary so we have those two columns now let's open Terminal and execute PHP art design migrate hit the enter okay that feels weird edit now let's open post.php model let's scroll up find the fillable and let's say it right here meta title and meta description perfect so we have model ready now let's open post resource scroll up in the form section so here is our form we have title in Slug yes title and slogan body and active well before active I'm going to duplicate this body and this should be text input oops text input from filament components like this and that should be meta title and let's remove required from here and let's duplicate this and this should be meta description so and let's make these text well it should be text input as well not text area so I'm going to save this and reload scroll down below we have meter type okay let's type right there my meta title in my meter in the description because we're going to just test the functionality it's it should not be like it cannot be actual data so um let's save these like the proper wording would be it might not be it is not mandatory to the proper data so just diameter will work okay I'm going to reload the page and actually we should go to that specific post let's copy slag and in the URL let's just paste this hit the enter so this is the post okay but we actually have not implemented anything we don't output these Meta Meta titles right here so we should do that but we also want me to titles to be outputted on the home page for example and on the about us page which are not at the moment um are not posts and they are not even pages and by the way these about us page is not linked properly so let's just quickly open app dot blade and find this about us here we go and let's change this into root about uh no it's it's probably about us here we go I click this and it goes right there so we need meta title limited description right here as well and then home and basically on categories page as well so we need this everywhere so I'm going to do in the following way in the app blade I will assume that this component will always receive meta title and meta description so instead of hard coding having a hard-coded text right here I'm going to change these in I'm going to try to Output meta title right there okay and if that does not exist or if this is empty let's assume that we will always pass that meta title okay and if this is empty then we can just output the code holic block or you can type your own blog name so let's just Define the author as well the code holic animated description we're going to Output right here in the same way meta and description and if that doesn't exist we can just leave this empty okay so now we are using always meet a title in meta description in the layout but we need to pass those variables to the layout right so let's open up layout component and in the Constructor let's take those two variables public string meta title is an empty string or null and public string and let's put a question mark right here in public string meta oops Meetup and description is also now okay so here we have two variables why is this all individual value question mark question mark is necessary right here okay so we have those two variables meta title in meta description and because we defined them with a public key those are class properties and they are available in the layout so if I just save this and reload the page we don't see anything nothing is passed right there but if I accept right here for example test save and reload and now look at this by the way so title is outputted right here okay and if we click view page Source we see title right here and by the way there also exists meta title but again uh and we can type like meta title right here but the latest version of search engines I'll look for the title text So Meta title is less important title is the is key so that's the most important thing so we're gonna just put the meter title right here okay perfect so we have implemented passing the data now how we're going to actually pass the correct data to the app layout let's start from the home I'm going to open homeblade PHP and we are using this app layout right here so now this layout which is a component yeah it accepts meta title and meta description so I'm going to pass Nita dish title to be something like the code holy blog or we can just leave this empty and because in the upper blade we are taking the code holic blog we can just leave this empty okay I'm not going to pass this meta tape title but instead I'm going to pass meta and description description and that should probably be the code holique code holix personal blog about coding tutorials okay so I save this reload the page and look at this the code holix personal blog about coding tutorials and right here we see the code call it block and that is passed by the way are everywhere okay we're right now on the category page which should not be passed but it is still past we're going to fix that but the main thing is that if we go on the home page we see that the code holix Personnel blog about coding and this is the title okay so far so good now we have implemented the home page now let's go on the post page post Dot View so in the post view we accept post so we can take post meta title and post meter description and pass them meta title corresponds to post um title but if post meta title does not exist then let's take host title okay save click on this now click view page source and this is the title why JavaScript is weird Okay so this is our title we can also like prefix or suffix the blog the actual application name like the code holique blog we can prefix that or suffix that you can do this as you want like I'm going to leave this right now as it is why JavaScript is weird and we can also specify meta Dash description is post meter description so I saved it I reload nothing's password right here in y let's check this meter and description I think I have passed everything correctly if I go in the admin panel reload okay it was not saved yeah that was not saved like my meter title in my meta description save changes that will save reload the page that was lost why was that lost let's check post PHP this is why it was lost because I have two t right here save that okay perfect I reload the page my meta title and my description I'm going to click save reload the page that was actually saved and now if I reload the why JavaScript is weird and remove the page we see my meta title in my description which come from here okay so if I just delete my meter title and hit the enter that was saved reload the page now it's going to take the title actual post title from here okay it's a fallback and it's good good logic in my opinion so now we have implemented a passing meta titles and with the descriptions for the home page as well as for the Post view page okay what other rules do we have let's open web.php and have a look so we have about us page and we have Pi category page let's go on the about page right here which renders about that blade so let's open about blade PHP and in the same way we're going to pass like meta title and let's just type the code holique blog or maybe about the code holic or something like this like the code holix blog or something like this okay now there's about ask page that should be probably and of course we can specify meta and description you get the idea I'm just going to type lorem ipsum okay I saved it by the way if you pass this with a column uh you need to put this inside quotations okay because we need it expects like a variable at this moment but if you remove this column we can just remove this uh quotations as well save that and let's go on about Dash as page and here we see the code holdx plug and lorem ipsum perfect so we have implemented about us as well and the last thing is to implement the Page by category let's go in the post controller by category and that renders a whole but you know what rendering the same view for by category as we have rendered for for the home is not actually a good idea so maybe we need to go in the home and I'm going to copy this home and paste inside the post folder and I'm going to call this index maybe okay and in the index we know that um we let's go in the post by category and let's pass the category okay from here so we pass the category uh we render post.index right here and now if we open that index we know that we have right here category so maybe we can specify inside meta title to be like category title Maybe and meta description can be whatever whatever you want like um by category description or something like this so I save this now and click on the JavaScript which renders pull Spike diggery view page source and we see JavaScript which is actually the title now for the category right so the ideal title probably will be the code holique blog dish or maybe not Dash let's leave a dash posts by category in the actual category so I save and reload the code public blog post by category JavaScript okay that's very very logical title for that page and I guess it's not more than six characters as well so in the description you can type something like this as well and I think we are good so now we have titles for every page like on the home page view page Source we have implemented those uh we have implemented uh meta titles for the by category page about us page let's check this once again and I think that's perfect and whenever you create new post from the admin panel if you Define meta title and meet a description uh then you basically tell search engine that hey this this is the overall information about my post and then it helps basically search engine of course only meta title and meter description are not 100 enough to optimize your blog post or Otero websites or any Pages you can optionally add other titles like OG uh open graph titles for sharing your posts on Facebook or on social media and I really really recommend to do that and Implement those fields as well now let's do some final touches on a website let me first change the background color of the body at the moment it is white and we also have white cards on that so I'm going to change this into gray Dash 15 and let's remove this white I'm going to save and reload and now that's much better now if I scroll down below and zoom out slightly we see that the cards have actually background transparent so let's go in the post item find that article and give it class PG white save that and reload and now this one has a white background if we scroll at the very top and click this logo it doesn't do anything so I'm going to go in the categories section click right here it doesn't do anything so this should go to the home page so let's go in the up blade and find this the code holy blog and let's change this href into root home save refresh the page and click right here it goes to the home on the right side we have this about our section but whenever I click on this button it doesn't do anything we need to link this to the about us page so let's go in the sidebar find this button and we're going to change this into roads about Dash us save reload the page and click on this and we are on about us page okay let's scroll down below let's go in the JavaScript section when there are multiple categories on the post they are not on a single line they are each on its own line and we're going to change that I don't like this so let's go in the post item and right here we iterate over our categories so I'm going to create new div give it it should be div give it a class of flex and let's give it also gap of three for example or maybe even four and the closing tag goes right here we save the code and now let's reload the page and here we see now they are all categories on its own line and on a on the same line and if I click on this article right here we have the same thing and now if I click on this article and go inside uh right here there's the same problem so we're going to open a view.play.php find that category is rendering and basically I'm going to use the same class same div as a wrapper of this for each right here format the code and reload the page and voila on this article I added a code which are under pre-tax but they don't look like a code actually so let's add small CSS to identify that this is a code uh block of code so in the app play in the layout just like we have the fun family Carla I'm going to create a small CSS I'm not doing this in a separate CSS file because it's very small and very minimalistic like on pre we're going to have padding to be one ram let's give it a background color to be like a gray or black let's give it color to be white and let's give it border radius to be 0.5 Ram and let's save this and have a look reload the page and this is it I think this is exactly what I wanted so and let's give this also margin bottom like one ram like this say reload and this is exactly what I wanted that's it guys in this video and I hope you enjoyed it if you want to see how I built a full stack application with the react and lateral click right here if you prefer view JS you should check the following video otherwise I will see you in the next time
Info
Channel: The Codeholic
Views: 86,050
Rating: undefined out of 5
Keywords: TheCodeholic, php, learn php, php tutorial, laravel, laravel tutorial, laravel project, laravel 10, laravel 10 project, laravel 10 tutorial, laravel blog, laravel blog project, laravel build website, laravel 10 blog, laravel 10 website, laravel project tutorial, laravel blog website, laravel docker, laravel 10 sail, laravel 10 admin panel, laravel admin panel, laravel website with admin panel, laravel blog with admin panel, laravel filament, laravel filament PHP
Id: iVThaG_sAt0
Channel Id: undefined
Length: 177min 6sec (10626 seconds)
Published: Mon Mar 13 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.