How to pass variables to a custom panel field?

#1

Is it possible to create a custom panel field in kirby 3 (email-button, pdf-button) that uses fields from the page where it is used? Is there a tutorial for this? Is it possible to use the $site, $page variables in a custom panel field? Or how can variables be passed to this. Thanks for any advise.

0 Likes

Custom field save hook
#2

I’m not exactly sure what you are looking for, could you explain a bit more what those fields would do and what they’d need to access ?

On a general note, $kirby, $site, etc. variables aren’t defined in plugins, you’ll need to call them with kirby() and site().

0 Likes

#3

I have to create a mailbutton in the panel of a specific page and it has to be able to sent an email to the (‘email’)field on that page with some content of that specific page.

0 Likes

#4

How I’d solve this:

  • Custom Field: A button with a click event that sends a request with the current page id to a custom route.
  • A custom route that finds the page and its content and does the email job (also includes checks for authentication and permissions)

How to create a field is in the docs, also the custom route. The call to the backend can be done with the Panel $api or your own fetch() function. And the email is sent with Kirby’s email engine

0 Likes

#5

This is very similar to what I need: the button should change the value of a field of the page. Would you still use a route for this? Thx for any help!

0 Likes

#6

@piaaaac this sounds more like something you can do directly in the panel without a custom route, but it depends of course on your exact needs.

0 Likes

#7

Actually my explanation was very poor. It’s dealing with subpages, like this:

Each row should be a subpage (planning to use kirby-pagetable). In review, Accepted and Refused are links (or ideally buttons) that when pressed do 2 things:

  • send an email to the user’s email
  • change page’s admin-status according to clicked link

I can think of hacky ways of doing it but since Kirby3 is awesome I’d like to learn using it properly (:

1 Like

#9

You actually don’t have to nest panel routes searching for the id. A field comes with the ability to register its own API routes. Inside this route you can access the parent’s content with $this->model().

Untested but hopefully this could get you started (assuming your email is stored in a field called emailfield):

// plugins/email-button/index.php
Kirby::plugin('custom/email-button', [
    'fields' => [
    	'email-button' => [
            'api' => function() {
 				return [
 					[
		                'pattern' => 'send-email',
		                'action' => function () {
                            // check authentication first

		                	$address = $this->field()->model()->emailfield()->value();

		                	// $emailContent = Compile your content

		                	try {
							    kirby()->email([
							    	'from'    => 'welcome@supercompany.com',
							    	'to'      => $address,
							    	'subject' => 'Updated content',
							        'body'    => $emailContent,
							    ]);
							} 
							catch (Exception $error) {
							    // act on error
							}
		                }
 					]
 				]
            },
        ]
    ]
]); 

Then in your JS:

// plugins/email-button/index.js
panel.plugin('custom/email-button', {
    fields: {
        'email-button': {
            props: {
            	endpoints: Object,
            },
            methods: {
            	sendEmail() {
            		this.$api.post(this.endpoints.field + '/send-email')
            		    .then(function(response) {
				            // do something
				        })
				        .catch(function(error) {
				            // do something
				        });
            	}
            },
            template: `
		        <button class="email-button" @click="sendEmail"></button>
		    `
		}
	} 
});
3 Likes

#10

@sylvainjule two amendmends to your php code:
$this->model() should be $this->field()->model() and $kirby seems not yet to exist in that context.

// plugins/email-button/index.php
Kirby::plugin('custom/email-button', [
    'fields' => [
        'email-button' => [
            'api' => function() {
                return [
                    [
                        'pattern' => 'send-email',
                        'action' => function () {
                            // check authentication first
                            
                            $address = $this->field()->model()->emailfield()->value();

                            // $emailContent = Compile your content

                            try {
                                kirby()->email([
                                    'from'    => 'welcome@supercompany.com',
                                    'to'      => $address,
                                    'subject' => 'Updated content',
                                    'body'    => $emailContent,
                                ]);
                            }
                            catch (Exception $error) {
                                // act on error
                            }
                        }
                    ]
                ];
            },
        ]
    ]
]); 
2 Likes

#13

@sylvainjule,
when i place the files in my plugins folder in a folder “email-button”, i got a blank page on my site. I guess there must be something wrong in the code, or maybe i am missing something.
I replaced :

$address = "test@test.be";  
$emailContent = "Compiled content";

full code:

// plugins/email-button/index.php

Kirby::plugin('custom/email-button', [
    'fields' => [
        'email-button' => [
            'api' => function() {
                return [
                    [
                        'pattern' => 'send-email',
                        'action' => function () {
                            // check authentication first

                            $address = "test@test.be";  
                            $emailContent = "Compiled   content";

                            try {
                                kirby()->email([
                                    'from'    => 'webform@test.be',
                                    'to'      => $address,
                                    'subject' => 'Updated content',
                                    'body'    => $emailContent,
                                ]);
                            } 
                            catch (Exception $error) {
                                // act on error
                            }
                        }
                    ]
                ]
            },
        ]
    ]
]); 

// plugins/email-button/index.js

panel.plugin('custom/email-button', {
    fields: {
        'email-button': {
            props: {
              endpoints: Object,
            },
            methods: {
              sendEmail() {
                this.$api.post(this.endpoints.field + '/send-email')
                    .then(function(response) {
                    // do something
                })
                .catch(function(error) {
                    // do something
                });
              }
            },
            template: `
            <button class="email-button" @click="sendEmail"></button>
            `
    }
  } 
});

I work local on Mamp.

0 Likes

#15

Please give us a bit more information about your error.
Where do you get a blank page? What does your php error log say? An output in the js console? What does your blueprint look like?

Be aware that the given code sample is very basic and does not include full error handling or permission/auth checks.

0 Likes

#16

Hi,
Now i made it work. I receive the email, but in my console i still get a 404-error in app.js

POST http://localhost:7880/mysite/api/pages/about/fields/email-button/send-email 404 (Not Found)

{status: "error", message: "not found", code: 404}

my template looks like:

        fields:                    
          emailfield:
            label: emailfield 
            type: email
          email-button:
            type: email-button
          text:
            label: Text
            type: textarea
            size: medium

Any ideas why i get these errors and how to get rid of them? Thanks!

0 Likes

#19

You are not sending anything back to the panel from your field route, which seems to end in a 404 code.

You could find out about the email status and return it.

return ['status' => 'success']
0 Likes

#20

this works, no errors anymore! thanks!

0 Likes

#21

How can I pass data to this custom field api endpoints? And is this documented somewhere? I tried to find it in the kirby source code but I’m not sure where to look.

0 Likes

#22

Okay, I found it (example code not tested)
When using get request:

// index.php
Kirby::plugin('custom/field', [
  'fields' => [
    'custom-field' => [
      'api' => function() {
        return [
          [
            'pattern' => 'do-something',
            'method' => 'get'
            'action' => function() {
              $test = $this->requestQuery('test');
            }
          ]
        ];
      }
    ]
  ]
]);

// index.js
this.$api.get(this.endpoints.field + '/do-something', { test: 'mhhh' })

when using post:

// index.php
Kirby::plugin('custom/field', [
  'fields' => [
    'custom-field' => [
      'api' => function() {
        return [
          [
            'pattern' => 'do-something',
            'method' => 'post'
            'action' => function() {
              $test = $this->requestBody('test');
            }
          ]
        ];
      }
    ]
  ]
]);

// index.js
this.$api.post(this.endpoints.field + '/do-something', { test: 'mhhh' })

api source code

0 Likes