Question about routing

Hello,

I am currently building a website for an architectural studio.
I am doubting about the right way to build the portfolio section.

My idea:

Projects
example.com/projects

Projects category overview
example.com/projects/category

Project (single)
example.com/project

So then I want/should make a re-route for a single project to ged rid of the /projects/category part of the URL. This is better for SEO because the project is not so deep in the url (less folders). But is this even possible?

Thanks you for your answer!

How many projects are we talking about? Hundreds? Thousands?

I think around 150/200 projects and about 8 categories.

Then you would probably be more flexible without the category pages, and assigning the categories via a select/multiselect field.

But to answer your original question: yes, routing would be possible with the structure above.

And then filter with the tags collection method?

Yes, or filter with routes.

Allright thank you for your help!

I am not able to get it working.
What I want to achieve is:

Projects
example.com/projecten

Projects category overview
example.com/projecten/category for example example.com/projecten/interior

Project (single)
example.com/projecten/name-project

I have:

Controller (same name as page template):
projects.php

<?php

return function ($page, $category) {

$projects = $page->children()->listed();

if ($category) {
    $projects = $projects->filterBy('category', ',');
}

return [
    'projects' => $projects
];

};

config.php

<?php

return [
    'debug' => true,
    'routes' => [
        [
            'pattern' => 'projecten/(:any)',
            'action' => function ($category) {
                if ($page = page('projecten/' . $category)) {
                    return $page;
                } else {
                    return page('projecten')->render([
                        'category' => $category
                    ]);
                }

            }
        ]
    ]
];

and as template for projecten:

<?php snippet('header') ?>

    <div id="hero-and-body">
        <section id="page-body">
            <div id="portfolio-grid" class="isotope-grid portfolio-container style-column-3 fitrows clearfix text-light">

                <?php foreach ($page->children()->listed() as $project): ?>

                    <div class="isotope-item portfolio-item">
                        <div class="portfolio-item-inner item-inner">
                            <a href="<?= $project->url() ?>" class="thumb-hover overlay-color scale text-light">
                                <?php if ($image = $project->image()) : ?>
                                    <?= $project->images()->findBy("template", "cover")->crop(900, 506) ?>
                                        <?php endif ?>

                                            <div class="overlay-caption hidden">
                                                <span class="caption-sub portfolio-category"><?= $project->location() ?></span>
                                                <h4 class="caption-name portfolio-name"><strong><?= $project->headline() ?></strong></h4>
                                            </div>
                            </a>
                        </div>
                    </div>

                    <?php endforeach ?>

            </div>

        </section>
    </div>

    <?php snippet('footer') ?>

Blueprint:

  category:
    label: Categorie
    type: multiselect
    min: 1
    max: 8
    options:
      - Example 1
      - Example 2
      - Example 3
      - Example 4
      - Example 5
      - Example 6
      - Example 7
      - Example 8

That line is not quite complete:


$projects = $projects->filterBy('category', $category, ',');

Thanks for your respons!
I am able to see the page now but still seeing al the projects (from different categories). Do I have the page template as well?

example.com/projecten
example.com/projecten/interior
Show the same projects.

Thanks!

You are not using the $projects variable in your template!

This cannot work as expected.

<?php foreach ($projects as $project): ?>

Sorry, I don’t understand what to do.
If I change $project to $projects it still not works.

Do I have to filter by category? I only do understand how to filter for a specific category, not for all.

$projects = $projects->filterBy('category', $interior, ',');

What is $interior, and could you post your revised files again together with your folder structure.

$interior is one of the categories I use in my blueprint dropdown (for categories). Given your response, I suspect that this is also incorrect.

This is my page template:

<?php snippet('header') ?>
    <div id="hero-and-body">
        <section id="page-body">

            <div id="portfolio-grid" class="isotope-grid portfolio-container style-column-3 fitrows clearfix text-light">

                <?php foreach ($projects as $project): ?>

                    <div class="isotope-item portfolio-item">
                        <div class="portfolio-item-inner item-inner">
                            <a href="<?= $project->url() ?>" class="thumb-hover overlay-color scale text-light">
                                <?php if ($image = $project->image()) : ?>
                                    <?= $project->images()->findBy("template", "cover")->crop(900, 506) ?>
                                        <?php endif ?>

                                            <div class="overlay-caption hidden">
                                                <span class="caption-sub portfolio-category"><?= $project->location() ?></span>
                                                <h4 class="caption-name portfolio-name"><strong><?= $project->headline() ?></strong></h4>
                                            </div>
                            </a>
                        </div>
                    </div>

                    <?php endforeach ?>

            </div>

        </section>
    </div>

    <?php snippet('footer') ?>

Folder structure:

Site

  • accounts (not relevant children)
  • blueprints (not relevant children)
  • cache (not relevant children)
  • config
    • config.php
  • controllers
    • project.php
    • projects.php
    • search.php
  • plugins (not relevant children)
  • sessions (not relevant children)
  • snippets
    • header
    • footer
  • templates
    • default.php
    • home.php
    • projects.php
    • project.php
    • search.php
    • error.php

Oh, sorry for not clearly expressing myself, when I say site structure I mean the structure in your content folder…

Oh, and I also need the controller…

Not related to the original problem, but this piece of code in your template doesn’t make sense:

<?php if ($image = $project->image()) : ?>
  <?= $project->images()->findBy("template", "cover")->crop(900, 506) ?>
<?php endif ?>

What’s the point of the if statement here? It has no relation with the code inside the if-statement. What it should probably be:

<?php if ($image = $project->images()->findBy('template', 'cover')) : ?>
  <?= $image->crop(900, 506) ?>
<?php endif ?>

Folder Content:

  • 1_projecten
    • 1_greenhouse
      • greenhouse.jpg
      • gereenhouse.jpg.txt
      • project.txt
    • 2_boticelli
    • 3_lencester
  • 2_nieuws
  • 3_over
  • error
  • site.txt

Controller

   <?php

    return function ($page, $category) {

    $projects = $page->children()->listed();

    if ($category) {
        $projects = $projects->filterBy('category', $category, ',');
    }

    return [
        'projects' => $projects
    ];

};

You are totally right. Thanks!
I think it’s because of my limited PHP skills. Sorry!

Ok, but anyway, if you put together the template, the controller and the route, the code should work as expected.

If it still doesn’t, please send me a download link to the project via PM and I can have a look. That will be faster than trying to find the issue here.

I think you missed the close parenthesis ‘)’
->findBy(‘template’, ‘cover’)) : ?>

          <?php if ($image = $project->images()->findBy('template', 'cover')) : ?>
          <?= $image->crop(900, 506) ?>
          <?php endif ?>