Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modular content of foreign pages #988

Closed
laszlokorte opened this issue Aug 17, 2016 · 6 comments
Closed

Modular content of foreign pages #988

laszlokorte opened this issue Aug 17, 2016 · 6 comments

Comments

@laszlokorte
Copy link

laszlokorte commented Aug 17, 2016

it would be great if something like this was possible:

sidebar:
    items: 
        - '@page.modular': '/boxes/_contact'
        - '@page.modular': '/boxes/_download-latest'

My use case is the following: I have 5 info boxes that appear on several pages in the sidebar.
Eg the homepage and the contact page both have an info box with contact information in the sidebar. And a few other pages all have the same "download the latest version" box in the sidebar.

I do not want to duplicate those boxes across all pages because it's tiresome to update them once their content changes. I just want to create each box once and then include them into each pages sidebar collection.

Currently it's only possible to include single pages via @page.self: /my/page into a collection but from my point of view my boxes are not real pages but modular fragments so I would prefer to create them as modular (boxes/_contact instead of boxes/contact) but @page.self: /my/_page is not working. ( I guess because it relies on the page being routable?)
Creating the boxes as real pages instead of modular fragments also has the disadvantage that the twig template is not automatically rendered.
So if I do @page.self: /boxes/contact and in my parent page's template:

{% for module in page.collection('sidebar') %}
{{ module.content }}
{% endfor %}

while having the page defined as /boxes/contact/white-box.md and an templates/white-box.html.twig in my theme,
the module.content which is printed inside the loop does not consist of the rendered white-box template but just contains the plain markdown content. So currently I have to workaround this by doing:

{% for module in page.collection('sidebar') %}
{% include 'modular/' ~ module.template ~ '.html.twig' with {'page': module} only %}
{% endfor %}

I hope my use case is understandable. It would be really cool if it was possible to add single modular fragments from other pages to a page's collection and get their modular template rendered correctly when outputting the collection items.

@rhukster
Copy link
Member

Actually looking at this, it seems that @page.modular would actually be exactly the same as @page.self except it needs to look for all.

Try this.. in Pages.php.. around line 2367, you should see this:

$page = $this->find($params[0]);

if you change this to:

$page = $this->find($params[0], true);

Then - '@page.self': '/boxes/_contact' works as expected right?

@laszlokorte
Copy link
Author

laszlokorte commented Aug 18, 2016

I guess you are talking about the Page.php (singular). Adding the true parameter did not change anything. But a few lines further down I noticed the collection got filtered:
$results = $results->nonModular()->published();

Removing the the call to nonModular resolved my issue even without adjusting the find() call you mentioned.
Probably just removing the nonModular filtering here is not the right solution because it's needed for @page.childrenand @page.descendants. But for now it's working for me. Thanks 👍

@rhukster
Copy link
Member

rhukster commented Aug 18, 2016

ok try replacing the current lines 2375 - 2401 with:

                // Handle a @page.descendants
                if (!empty($parts)) {
                    switch ($parts[0]) {
                        case 'modular':
                            $results = new Collection();
                            $results = $results->addPage($page)->Modular();
                            break;
                        case 'self':
                            $results = new Collection();
                            $results = $results->addPage($page)->nonModular();
                            break;

                        case 'descendants':
                            $results = $pages->all($page)->remove($page->path())->nonModular();
                            break;

                        case 'children':
                            $results = $page->children()->nonModular();
                            break;
                    }
                } else {
                    $results = $page->children()->nonModular();
                }

                $results = $results->published();

                break;

Then try with @page.modular as you had it originally

@laszlokorte
Copy link
Author

works like a charm 👍

@rhukster
Copy link
Member

Cool will commit it then :)

@Kiouze
Copy link

Kiouze commented May 27, 2017

Hello ! I'm sorry but I don't understand if it is possible in the latest version of grav to call a modular on another page :(

I tryed to do as you instructed without success. Can you please help ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants