Jump to content
psy

[solved] How to programmatically create a FieldsetPage & add fields to it?

Recommended Posts

In my code, I create all the fields I want included in the FieldsetPage - all good. I then create my FieldsetPage field and it appears in the Admin->Fields list - seems all good.

		$fields = wire('fields');

		if(!$fields->get("name=widget_title")) {
            $field = new Field;
            $field->type = $modules->get("FieldtypeText");
            $field->name = "widget_title";
            $field->label = $this->_("Message Title");
            $field->description = $this->_("Max length 64 characters.");
            $field->maxlength = 64;
            $field->stripTags = true;
            $field->tags = "widget";
            $field->set('showCount', InputfieldText::showCountChars);
            $field->save();
        }

        // Fieldset page (requires PW v3.0.74 or later)

        if(!$fields->get("name=fspage_widget")) {
            $widget = new Field;
            $widget->type = $modules->get("FieldtypeFieldsetPage");
            $widget->name = "fspage_widget";
            $widget->label = $this->_('My Widget');
            $widget->tags = "widget";
            $fields->save($widget);
        }


Problem arises when I try to add fields to the FieldsetPage. While the field is created, the template and field group are not. When I try to add via code, eg

 

        $widget = $fields->get("name=fspage_widget");

            $templateName = FieldtypeRepeater::templateNamePrefix . $widget->name; // Correct name but no template yet assigned to FSPage field
            $template = $templates->get($templateName); // results in NULL
            $fg = $template->fieldgroup; // Ditto due to above
            $titleFld = $fields->get("name=widget_title");
            $fg->add($titleFld);
            $fg->save(); // No fieldgroup so no save

it falls over with NULL template and NULL fieldgroup.

I can manually add fields to the FieldsetPage via the admin field edit screen, at which point the appropriate template & fieldgroup get generated.

If I try to force the creation of the template in my code when I create the field, I end up with 2 templates - repeater_fspage_widget and repeater_fspage_widget1. That leads to all kinds of madness and no fields appear in the admin edit screen for 'fspage_widget' even though the field(s) I add show they're attached to a template.

It's all clearly visible in the database.

I've read everything I can find including the actual code and this forum article:

In this scenario, the fieldsetPage fields with their templates & fieldgroups already exist and are being migrated. Even @ryan says a the end:

Quote

Also wanted to add that programatically it should be identical to working with a regular PW fieldset type. 

 

So, question is, after adding a new FieldsetPage field via code, how do I programmatically add its template, fieldgroup & fields?

Share this post


Link to post
Share on other sites

@adrian and @thetuningspoon thanks! 🤩

 

Needed some tweakage as FieldsetPage, although based on Repeater, only has one page, not a number of child pages under the repeater page, in admin. Got it working with:

    /**
     * Creates a fieldsetpage field with associated fieldgroup, template, and page
     *
     * @param string $repeaterName The name of your fieldsetpage field
     * @param string $repeaterFields List of field names to add to the fieldsetpage, separated by spaces
     * @param string $repeaterLabel The label for your fieldsetpage
     * @param string $repeaterTags Tags for the fieldsetpage field
     * @return Returns the new FeildsetPage field
     *
     */
    public function createFieldsetPage($repeaterName,$repeaterFields,$repeaterLabel,$repeaterTags)
    {
        $fieldsArray = explode(' ',$repeaterFields);

        $f = new Field();
        $f->type = $this->modules->get("FieldtypeFieldsetPage");
        $f->name = $repeaterName;
        $f->label = $repeaterLabel;
        $f->tags = $repeaterTags;
        $f->save();


        //Create fieldgroup
        $repeaterFg = new Fieldgroup();
        $repeaterFg->name = "repeater_$repeaterName";

		//Add fields to fieldgroup
		foreach($fieldsArray as $field) {
            $repeaterFg->append($this->fields->get($field));
        }

		$repeaterFg->save();

		//Create template
		$repeaterT = new Template();
		$repeaterT->name = "repeater_$repeaterName";
		$repeaterT->flags = 8;
		$repeaterT->noChildren = 1;
		$repeaterT->noParents = 1;
		$repeaterT->noGlobal = 1;
		$repeaterT->slashUrls = 1;
		$repeaterT->fieldgroup = $repeaterFg;

		$repeaterT->save();

        // Create the admin/repeaters page (different to standard repeaters)
        // add more options to the page if you prefer
        $repeaterPage = new Page();
        $repeaterPage->of(false);
        $repeaterPage->template = 'admin';
        $repeaterPage->name = "for-field-" . $f->id;
        $repeaterPage->title = $f->name;
        $repeaterPage->parent_id = $this->pages->get("path=/admin/repeaters/");
        $this->pages->save($repeaterPage);

        // Associate the FieldsetPage field with the new admin/repeater page
		$f->parent_id = $this->pages->get("name=$repeaterPage")->id;
		$f->template_id = $repeaterT->id;

		//Now, add the fields directly to the FieldsetPage field
		foreach($fieldsArray as $field) {
            $f->repeaterFields = $this->fields->get($field);
        }

		$f->save();

		return $f;
	}

and example usage:

        $fsPageName = "fspage_widget";
        $fsPageFields = "widget_title";
        $fsPageLabel = _("My Widget");
        $fsPageTags = "widget";

        $f = $this->createFieldsetPage($fsPageName,$fsPageFields,$fsPageLabel,$fsPageTags);

 

  • Like 5

Share this post


Link to post
Share on other sites

Awesome - glad you got it working and thanks for sharing the solution!

 

  • Like 1

Share this post


Link to post
Share on other sites

There's one addition which maybe makes your live a bit easier – if name of admin area is not "admin":

$pageAdmin = $this->pages->get('title=Admin');
$repeaterPage->parent_id = $this->pages->get('path=/'.$pageAdmin->name.'/repeaters/');

 

  • Like 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Matze
      Hi,
      is there a way to activate the option Input > Visibility > Presentation > "Open when populated + Closed when blank" for a Fieldset (Page) containing some fields like text or textarea?
      To me it is always open, even if all fields inside are empty.
      Thx, Matze
×
×
  • Create New...