Log1x / acf-composer

Compose ACF Fields, Blocks, Widgets, and Option Pages with ACF Builder on Sage 10.
https://github.com/Log1x/acf-composer
MIT License
414 stars 56 forks source link

Options: children #93

Closed davideprevosto closed 6 months ago

davideprevosto commented 3 years ago

Hello,

I would like to organize our ACF Pro options pages in a simple tree, using the parent functionality:

-- Sections (without fields) ---- First Option (with fields) ---- Second Option (with fields)

Unfortunately it seems something wrong, the generated links are:

https://test.lndo.site/wp-admin/admin.php?page=first (right) https://test.lndo.site/wp-admin/second (wrong, 404. It should be https://test.lndo.site/wp-admin/admin.php?page=second)

image

I have created a brand new Sage 10 project, excluding any other plugin or custom code, I have just used wp acorn commands.

Sections.php

<?php

namespace App\Options;

use Log1x\AcfComposer\Options as Field;
use StoutLogic\AcfBuilder\FieldsBuilder;

class Sections extends Field
{
    /**
     * The option page menu name.
     *
     * @var string
     */
    public $name = 'Sections';

    /**
     * The option page menu slug.
     *
     * @var string
     */
    public $slug = 'sections';

    /**
     * The option page document title.
     *
     * @var string
     */
    public $title = 'Sections | Options';

    /**
     * The option page permission capability.
     *
     * @var string
     */
    public $capability = 'edit_theme_options';

    /**
     * The option page menu position.
     *
     * @var int
     */
    public $position = PHP_INT_MAX;

    /**
     * The slug of another admin page to be used as a parent.
     *
     * @var string
     */
    public $parent = null;

    /**
     * The option page menu icon.
     *
     * @var string
     */
    public $icon = null;

    /**
     * Redirect to the first child page if one exists.
     *
     * @var boolean
     */
    public $redirect = true;

    /**
     * The post ID to save and load values from.
     *
     * @var string|int
     */
    public $post = 'options';

    /**
     * The option page autoload setting.
     *
     * @var bool
     */
    public $autoload = true;

    /**
     * Localized text displayed on the submit button.
     *
     * @return string
     */
    public function updateButton()
    {
        return __('Update', 'acf');
    }

    /**
     * Localized text displayed after form submission.
     *
     * @return string
     */
    public function updatedMessage()
    {
        return __('Sections Updated', 'acf');
    }

    /**
     * The option page field group.
     *
     * @return array
     */
    public function fields()
    {
    }
}

First.php

<?php

namespace App\Options;

use Log1x\AcfComposer\Options as Field;
use StoutLogic\AcfBuilder\FieldsBuilder;

class First extends Field
{
    /**
     * The option page menu name.
     *
     * @var string
     */
    public $name = 'First';

    /**
     * The option page document title.
     *
     * @var string
     */
    public $title = 'First | Options';

    /**
     * @var string
     */
    public $parent = 'sections';

    /**
     * The option page field group.
     *
     * @return array
     */
    public function fields()
    {
        $first = new FieldsBuilder('first');

        $first
            ->addRepeater('items')
                ->addText('item')
            ->endRepeater();

        return $first->build();
    }
}

Second.php

<?php

namespace App\Options;

use Log1x\AcfComposer\Options as Field;
use StoutLogic\AcfBuilder\FieldsBuilder;

class Second extends Field
{
    /**
     * The option page menu name.
     *
     * @var string
     */
    public $name = 'Second';

    /**
     * The option page menu slug.
     *
     * @var string
     */
    public $slug = 'second';

    /**
     * The option page document title.
     *
     * @var string
     */
    public $title = 'Second | Options';

    /**
     * The option page permission capability.
     *
     * @var string
     */
    public $capability = 'edit_theme_options';

    /**
     * The option page menu position.
     *
     * @var int
     */
    public $position = PHP_INT_MAX;

    /**
     * The slug of another admin page to be used as a parent.
     *
     * @var string
     */
    public $parent = 'sections';

    /**
     * The option page menu icon.
     *
     * @var string
     */
    public $icon = null;

    /**
     * Redirect to the first child page if one exists.
     *
     * @var boolean
     */
    public $redirect = true;

    /**
     * The post ID to save and load values from.
     *
     * @var string|int
     */
    public $post = 'options';

    /**
     * The option page autoload setting.
     *
     * @var bool
     */
    public $autoload = true;

    /**
     * Localized text displayed on the submit button.
     *
     * @return string
     */
    public function updateButton()
    {
        return __('Update', 'acf');
    }

    /**
     * Localized text displayed after form submission.
     *
     * @return string
     */
    public function updatedMessage()
    {
        return __('Second Updated', 'acf');
    }

    /**
     * The option page field group.
     *
     * @return array
     */
    public function fields()
    {
        $second = new FieldsBuilder('second');

        $second
            ->addRepeater('items')
                ->addText('item')
            ->endRepeater();

        return $second->build();
    }
}

Is anyone experiencing the same issue?

Thank you!

monkeymonk commented 3 years ago

Hello there, it seems that your "$post" (eg. ID) are not in sync with your "$parent".

First.php and Second.php does not need a "$post" and since the "$parent" are set to "sections", the "$post" from Sections.php should be "sections" as well.

davideprevosto commented 3 years ago

Hello there, it seems that your "$post" (eg. ID) are not in sync with your "$parent".

First.php and Second.php does not need a "$post" and since the "$parent" are set to "sections", the "$post" from Sections.php should be "sections" as well.

Thank you for your reply @monkeymonk.

I have tried to edit and keep the example code as simple as possible.

Right now I have only 3 files:

/* Sections.php */

<?php

namespace App\Options;

use Log1x\AcfComposer\Options as Field;

class Sections extends Field
{
    /**
     * The option page menu name.
     *
     * @var string
     */
    public $name = 'Sections';

    /**
     * The post ID to save and load values from.
     *
     * @var string|int
     */
    public $post = 'sections';

    /**
     * The option page field group.
     *
     * @return array
     */
    public function fields()
    {
      // empty stub
    }
}

/*------------------------------------------------------------------------*/

/* First.php */

<?php

namespace App\Options;

use Log1x\AcfComposer\Options as Field;
use StoutLogic\AcfBuilder\FieldsBuilder;

class First extends Field
{
    /**
     * The option page menu name.
     *
     * @var string
     */
    public $name = 'First';

    /**
     * @var string
     */
    public $parent = 'sections';

    /**
     * The option page field group.
     *
     * @return array
     */
    public function fields()
    {
        $first = new FieldsBuilder('first');

        $first
            ->addRepeater('items')
                ->addText('item')
            ->endRepeater();

        return $first->build();
    }
}

/*------------------------------------------------------------------------*/

/* Second.php */

<?php

namespace App\Options;

use Log1x\AcfComposer\Options as Field;
use StoutLogic\AcfBuilder\FieldsBuilder;

class Second extends Field
{
    /**
     * The option page menu name.
     *
     * @var string
     */
    public $name = 'Second';

    /**
     * The slug of another admin page to be used as a parent.
     *
     * @var string
     */
    public $parent = 'sections';

    /**
     * The option page field group.
     *
     * @return array
     */
    public function fields()
    {
        $second = new FieldsBuilder('second');

        $second
            ->addRepeater('items')
                ->addText('item')
            ->endRepeater();

        return $second->build();
    }
}

Unfortunately I am getting the same issue. Output links are:

1) https://test.lndo.site/wp-admin/admin.php?page=first (that's right) 2) https://test.lndo.site/wp-admin/second (wrong)

Deleting First.php file, the 2) link is going to be the right one.

I can't see what I am missing.

Thank you

Twansparant commented 2 years ago

I've got the same problem, would like to know if there's a fix.

Twansparant commented 2 years ago

I discovered this is also a priority/order issue, if you dump $this here, you will see the order of the options pages it's trying to add. The ones that fail are loaded before the parent options page. I tried to be smart by adding underscores __ to the parent options file to make sure it's loaded first, but that doesn't help.

I fixed it by defining the parent options page in the acf/init hook instead of in AcfComposer:

add_action('acf/init',  'init_options');
function init_options() {
    $option_page = acf_add_options_page([
        'page_title' => __('Sections | Options'),
        'menu_title' => __('Sections'),
        'menu_slug'  => 'sections,
        'position'   => 40,
        'redirection'   => true
    ]);
}

Now your options sub pages will be correct: https://test.lndo.site/wp-admin/admin.php?page=first https://test.lndo.site/wp-admin/admin.php?page=second

nahojj commented 2 years ago

I get the exact same issue when adding 2 children. Since this issue is from 2021, will there be any fix for this in the near future?

octoxan commented 1 year ago

Just ran into this same unfortunate issue and wasted some time trying to find a fix. Thanks @Twansparant for the workaround!

davideprevosto commented 6 months ago

Hello @Log1x, I noticed you solved the "issue", thank you. Using the 3.x version, can you share the right way to accomplish the described behaviour?

Thank you!

Log1x commented 6 months ago

Hello @Log1x, I noticed you solved the "issue", thank you. Using the 3.x version, can you share the right way to accomplish the described behaviour?

Thank you!

You should be able to just set the parent slug on child pages now and they will attach to parents. If not, open an issue. Make sure $redirect is false.