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

FR: Display nesting for Pages fieldtype #1685

Closed
FrittenKeeZ opened this Issue Dec 20, 2017 · 4 comments

Comments

Projects
None yet
2 participants
@FrittenKeeZ

FrittenKeeZ commented Dec 20, 2017

If you have a lot of pages nested in several levels, it becomes almost impossible to use the Pages fieldtype, as all pages are rendered in 1 level without showing nesting. This is especially difficult for pages with the same names in different paths, like:
/hotels/hotel-a/rooms
/hotels/hotel-b/rooms

@FrittenKeeZ

This comment has been minimized.

FrittenKeeZ commented Jan 15, 2018

Here's a custom SuggestMode which renders a nested list.

<?php

namespace Statamic\Addons\PagesNested;

use Statamic\Addons\Suggest\Modes\AbstractMode;
use Statamic\API\Content;
use Statamic\API\Page;
use Statamic\API\Str;

class PagesNestedSuggestMode extends AbstractMode
{
    /**
     * Get the suggestions.
     *
     * @return array
     */
    public function suggestions()
    {
        // Grab parent uri/id if specified or default to front page.
        $parent = $this->request->input('parent', '/');
        // Fetch the parent page.
        $parent = Str::startsWith($parent, '/') ? Page::whereUri($parent) : Page::find($parent);
        // Fetch the page tree with an optional depth.
        $tree = Content::tree($parent->uri(), $this->request->input('depth'));

        // Parent is front page unless specified, so prepend it to the tree.
        if (! $this->request->input('parent')) {
            array_unshift($tree, [
                'page'     => $parent,
                'depth'    => 1,
                'children' => [],
            ]);
        }

        return $this->generateSuggestions($tree);
    }

    /**
     * Generate nested suggestions for a Statamic\API\Content::tree().
     *
     * @param  array  $tree
     * @param  int    $level
     * @param  array  $suggestions
     * @return array
     */
    protected function generateSuggestions(array $tree, int $level = 0, array $suggestions = [])
    {
        // Each level above 0 is indented by &emsp;&ensp;&#8627;&ensp;.
        $indent = $level > 0 ? str_repeat('  ', $level - 1) . '↳ ' : '';

        foreach ($tree as $item) {
            $suggestions[] = [
                'value' => $item['page']->id(),
                'text'  => $indent . $this->label($item['page'], 'title'),
            ];

            // Grab suggestions for children.
            if (! empty($item['children'])) {
                $suggestions = $this->generateSuggestions($item['children'], $level + 1, $suggestions);
            }
        }

        return $suggestions;
    }
}

All options from the normal PagesMode are available, except sort.

@jasonvarga

This comment has been minimized.

Member

jasonvarga commented Jan 15, 2018

Awesome!
When were you seeing pages being added twice? What's the reason for // Only add page once.?

@FrittenKeeZ

This comment has been minimized.

FrittenKeeZ commented Jan 15, 2018

That's legacy code from a previous approach... I'll just update the snippet :)

@jasonvarga

This comment has been minimized.

Member

jasonvarga commented Jan 15, 2018

This is going in core as the default behavior for the pages fieldtype.

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