Symfony 2.8 Jobeet Day 7: Playing with the Category Page
Today we will make the Category page like it is described in the second day’s requirements: “The user sees a list of all the jobs from the category sorted by date and paginated with 20 jobs per page“.
The Category Route
First, let’s think about the route we will use for our category page. We will define a pretty URL that will contain the category slug: /category/{slug}
named category_show
.
To get the slug of a category we need to add the getSlug()
method to our category class:
The Category Link
Now, edit the index.html.twig
template of the job controller to add the link to the category page:
In the template above we used category.morejobs
, so let’s define it (src/AppBunlde/Entity/Category.php
):
The moreJobs
property will hold the number of active jobs for the category minus the number of jobs listed on the homepage. Now, in JobController, we need to set the moreJobs
value for each category:
The countActiveJobs
function has to be added to the JobRepository:
Now you should see the result in your browser:
The Job Category Controller
It’s now time to create the category controller. Create a new CategoryController.php
file in your Controller directory:
We could use the doctrine:generate:crud
command like we did for the job controller, but we won’t need 90% of the generated code, so we can just create a new controller from scratch.
Update the Database
We need to add a slug
column for the category table in src/AppBundle/Entity/Category.php
:
Remove from the Category entity the getSlug
method we created earlier and run the doctrine command to update the Category entity class:
php app/console doctrine:generate:entities AppBundle
Add the setSlugValue
function to be called on PrePersist
lifecycle callback (also don’t forget to add the @ORM\HasLifecycleCallbacks()
annotation at the beginning of the class):
Now we have to drop the database and create it again with the new Category column and load the fixtures:
php app/console doctrine:database:drop --force
php app/console doctrine:database:create
php app/console doctrine:schema:update --force
php app/console doctrine:fixtures:load
The Category Page
We have now everything in place to create the showAction()
method. Add the following code to the CategoryController.php
file:
The last step is to create the app/Resources/views/category/show.html.twig
template:
Including Other Twig Templates
Notice that we have copied and pasted the <table>
tag that create a list of jobs from the job index.html.twig
template. That’s bad. When you need to reuse some portion of a template, you need to create a new twig template with that code and include it where you need.
Create the app/Resources/view/job/list.html.twig
file:
You can include a template by using the using the {{ include() }}
function. Replace the <table>
HTML code from both templates with the include function:
{{ include('job/list.html.twig') }}
List Pagination
Although we have the KnpPaginatorBundle from KnpLabs, to solve this problem we will use the old classic method.
First, let’s add a page parameter to the category_show
route. The page parameter will have a default value of 1, so it will not be required:
@Route("/category/{slug}/{page}", defaults={"page": 1}, name="category_show")
The number of jobs on each page will be defined as a custom parameter in the app/config/config.yml
file:
parameters:
locale: en
max_jobs_on_homepage: 10
max_jobs_on_category: 20
Change the JobRepository getActiveJobs
method to include an $offset
parameter to be used by doctrine when retrieving jobs:
Change the CategoryController showAction
to the following:
Finally, let’s update the template to include the pagination code:
The result:
You can check the code from today here: https://github.com/dragosholban/jobeet-sf2.8/tree/day7
About the Author
Passionate about web & mobile development. Doing this at IntelligentBee for the last 5 years. If you are looking for custom web and mobile app development, please contact us here and let’s have a talk.