Jigsaw: Nested collections

Created on 20 Sep 2017  路  4Comments  路  Source: tighten/jigsaw

I find that if I have a long tree of nested objects like this:

subject > topic > course > lesson

I have to include the subject, topic, and course in every lesson file. What if this was stored in the config file somehow like this?

'collections' => [
   'lessons' => [
       'path' => '...',
       'sort'  => '...',
       'variables' => [
             'subject' => '...',
             'topic' => '...',
             'course' => '...',
        ]
   ],
   ...
]

That way I don't have repeat all these variables in every single lesson file. Thoughts?

2.0

Most helpful comment

Assuming subjects, topics, courses, and lessons are all collections, you could avoid duplicating all the extra variables in your markdown files by just specifying the immediate parent; it's always possible to reference up the hierarchy by accessing that parent collection.

So, for example:

  • lessons would only need a course variable, which would be the filename of the parent course (e.g. css-basics).
  • courses would only need a topic variable, with the filename of its parent (e.g. css)
  • topics would only need a subject variable, with the filename of its parent

Collection items are keyed by their filenames (not including any extension like .md or .blade.php. So, from within lessons, you can access the parent course collection item via $courses->get($page->course).

Let's say you wanted to output breadcrumbs for a lesson; you can traverse up the hierarchy in your Blade template, and get each parent collection item, like this:

@php
    $course = $courses->get($page->course);
    $topic = $topics->get($course->topic);
    $subject = $subjects->get($topic->subject);
@endphp

<a href="{{ $subject->getUrl() }}">{{ $subject->title }}</a> /
<a href="{{ $topic->getUrl() }}">{{ $topic->title }}</a> /
<a href="{{ $course->getUrl() }}">{{ $course->title }}</a>

You could even generalize these variables, and just name them all parent.

All 4 comments

How would you determine the value for each of subject, topic, and course in config.php? Seems that those would vary by file.

What you're doing is emulating nested collections, something that isn't fully supported at the moment. Ultimately, it would be best to allow collection items to live in subdirectories, and set them up in config like:

'collections' => [
    'subjects' => [
        'path' => '...',
        'collections' => [
            'topics' => [
                'path' => '...',
                'collections' => [
                    'courses' ...
                ],
            ],
        ],
    ],
]

Then, a collection item's position within a subdirectory (or subdirectories) would take the place of the extra subject/topic/course variables that you're currently specifying in the YAML header.

Yes, exactly! that is what I'm thinking. I find that I am resulting to that directory structure anyway to stay organized with all of my lessons. So instead of repeating myself with the variables it would be nice to setup the directory structure in config file, so I can remove all those variables from the files and update them in a single place.

Assuming subjects, topics, courses, and lessons are all collections, you could avoid duplicating all the extra variables in your markdown files by just specifying the immediate parent; it's always possible to reference up the hierarchy by accessing that parent collection.

So, for example:

  • lessons would only need a course variable, which would be the filename of the parent course (e.g. css-basics).
  • courses would only need a topic variable, with the filename of its parent (e.g. css)
  • topics would only need a subject variable, with the filename of its parent

Collection items are keyed by their filenames (not including any extension like .md or .blade.php. So, from within lessons, you can access the parent course collection item via $courses->get($page->course).

Let's say you wanted to output breadcrumbs for a lesson; you can traverse up the hierarchy in your Blade template, and get each parent collection item, like this:

@php
    $course = $courses->get($page->course);
    $topic = $topics->get($course->topic);
    $subject = $subjects->get($topic->subject);
@endphp

<a href="{{ $subject->getUrl() }}">{{ $subject->title }}</a> /
<a href="{{ $topic->getUrl() }}">{{ $topic->title }}</a> /
<a href="{{ $course->getUrl() }}">{{ $course->title }}</a>

You could even generalize these variables, and just name them all parent.

I ran into a similar issue...

Imagine you have the following:
Cars > Make > Model

You can do a "cars" page, you can do a collection of makes, but you can't do a nested collection of models.

So, for example, if I put a file in _cars/_fiat/panda.blade.php then I would expect to be able to reach it by visiting /cars/fiat/panda.

However, this currently appears to ignore the middle layer and will be called /cars/panda.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

slavarazum picture slavarazum  路  6Comments

Log1x picture Log1x  路  8Comments

DRogueRonin picture DRogueRonin  路  8Comments

pablood85 picture pablood85  路  8Comments

imaje89 picture imaje89  路  3Comments