Panelfield to open an url

i am looking for a panelfield to add a button to blueprint. the button should open the url set in another (hidden) field of the same blueprint ideally following the concept of select fields ‘options form other field’.

i need it for a newsletter blueprint. while viewing the data in the panel the user should be able to click a ‘send’ button. the url behind the button does the actual sending. ideally there is a warning if there are unsaved changes or the button is simply disabled if there are unsaved changes.

https://getkirby.com/docs/cheatsheet/panel-fields/select

my panelfield experience is close to zero. can anyone get me started? “panel-field-machine” @jenstornell maybe? :wink:

i once did see a clever solution here in the forum to use a structure to print custom data. i think it was an image preview in the entry pulled from the structure data. but i can not find it anymore.

Check out the boiler field by @jenstornell. It has everything you need to get you going with this.

In the template you would use a button instead of the input field and with some more modifications, it should work perfectly alright.

1 Like

Maybe it would be even simple to use the fragment field in this case. Then you only need to add a snippet.

Boiler or Fragment, you chosen. :slight_smile:

i managed to get create my ‘open this url’-button done using the fragment field. i can use some fancy ajax callbacks now, too. thanks. :yum:

URL creation
but i would like to improve how i create my url. since most of them are references to panel edit pages i was wondering if there is a function to get the ‘edit’ url other than building it myself.

http://localhost:8888/panel/pages/personen/max-mustermann/edit

currently i use the default field of the blueprint to create the url on panel ‘save’ using simple php str_replace.
note: i cant use {{VAR}} in default or it will get parsed as yaml array.

  editlinked:
    label: Buttons Label (optional)
    type: openurl
    text: Button Text
    default: site->url/panel/pages/page->parent->slug/page->slug/edit

the str_replace is called indirectly in site/fields/openurl.php

public function input() {
	// Load template with arguments
	$html = tpl::load( __DIR__ . DS . 'template.php', $data = array(
		'field' => $this,
		'page' => $this->page()
	));
	return $html;
} 

which loads a template starting like this

//... build url to open from default
$inputValue = $field->val();
$defaultValue = str_replace( 
    array('site->url',  'page->slug', 'page->parent->slug'), 
    array($site->url(), $page->slug(), $page->parent()->slug()), 
    $field->default);
//... output

what i am now trying to accomplish is something like a clickable page-field
maybe the page field could be extended as a custom field which only display a clickable button (not the auto-completing selector) if blueprint for the field has readonly: true. anybody done this already or tips to share?

You can, but you need to wrap the whole thing in quotes to make it a valid YAML string:

default: "{{site.url}}/panel/pages/{{parent.slug}}/{{page.slug}}/edit"

Or simpler:

default: pages/{{uri}}/edit

uri would be the page URI here. You then only need to run the whole thing through the url() helper.

1 Like

with

default: pages/{{uri}}/edit

the calling the url helper like this

$dflt = url($field->default);

does not replace {{uri}} nor {{page.url}}. i still need to do that myself right?

Sure, but the syntax is easier to understand, also you can use str::template:

$dflt = url(str::template($field->default, ['uri' => $page->uri()]));

However this will replace {uri} instead of {{uri}}, sorry for the confusion.

good tip to use str::template instead of str_replace. i still do not understand why i should call the url helper then? what does it do? i did not understand the codebase here.

the select field does have queries but i do not understand how they are added to the field class. maybe i could add queries to my custom field?

also i would like to know if its possible to get the current page object from within the panel field class.

It works just like in your templates. It does all the hard work for you so that you don’t have to add the hostname at the beginning. It returns an absolute URL of the relative path you give to it.

Sure: $this->page() from a method of your field class.

url helper. ah i see. i did not notice this because i used $page->url from beginning and not an uri. thanks for explaining.

$this->page() :stuck_out_tongue_closed_eyes: how could i miss that.

created a plugin for that