Adding to a text or info field in route via page->update()

I am trying to adda word to a text or info field via a POST route on config. This is the field on the blueprint:

...
fields:
  palabras:
    type: text
...

The following code on the route seems to ‘empty’ the text field, as in if the text field has any words, they are erased and the text field appears empty, literally.

$kirby = kirby();
$kirby->impersonate('kirby');
page('oraculo')->update([
	'palabras' => function($palabras) {
	    return $palabras =  $palabras . ' , ' . $palabra;
	}
], 'es');

I also tried return $palabras .= ' , ' . $palabra with the same result.

Additionally I would like to confirm I can do that even if the panel field has the ‘disabled’ option.

Thank you

As far as I know a force option to override a blueprint settings hasn’t been implemented yet.

What is the purpose of your callback here? That doesn’t make sense. Also, $palabras and $palabra are undefined variables (unless this is not the full code, but then you should post it, so that we don’t look at the wrong issues).

Thank you @pixelijn, the purpose of all this is to have a list of words stored in any kind of field, preferebly one that cannot be modified via the panel.

These words are sent via a POST call on the frontend and received from a route in the config file. The full route code (excuse the dirty chaining of validations):

	[
		'pattern' => '(:any)/oraculo',
		'method' => 'post',
		'action'  => function () {
			$palabra = get('palabra') ?? null;
			$recibir = get('recibir') ?? null;
			if ($palabra AND V::match($palabra, '/^([\pL])+$/u') AND V::maxWords($palabra, 1) AND V::maxLength($palabra, 27)) {
				$data = ['palabra_recibida' => true];
				$kirby = kirby();
				$kirby->impersonate('kirby');
				page('oraculo')->update([
					'palabras' => function($palabras) {
						return $palabras =  $palabras . ' , ' . $palabra;
					}
				], 'es');
			} elseif ($recibir) {
				$data = ['palabra_retornada' => true];
			} else {
				$data = ['error' => true];
			};
			return page('oraculo')->render($data);
		}
	],
]	

Let me know if you need anything else to help.

Thank you

In your example code, $palabras is not defined anywhere, so I guess you want to get the original field value from the page.

Also, to use the updated page, you have to store it in a variable.

[
		'pattern' => '(:any)/oraculo',
		'method' => 'post',
		'action'  => function () {
			$palabra  = get('palabra') ?? null;
			$recibir  = get('recibir') ?? null;
            $p        = page('oraculo');
            $palabras = $p->palabras()->value();
			if ($palabra AND V::match($palabra, '/^([\pL])+$/u') AND V::maxWords($palabra, 1) AND V::maxLength($palabra, 27)) {
				$data = ['palabra_recibida' => true];
				$kirby = kirby();
				$kirby->impersonate('kirby');
				$p = $p->update([
					'palabras' => $palabras . ' , ' . $palabra,
				], 'es');
			} elseif ($recibir) {
				$data = ['palabra_retornada' => true];
			} else {
				$data = ['error' => true];
			};
			return $p->render($data);
		}
	],

Thank you,

That is giving me a 500 error across the site.

The significant change I notice is that you don’t do the update via callback but directly, are you sure this syntax is correct ?

	$p = $p->update([
		'palabras' => $palabras . ' , ' . $palabra;
	], 'es');

…updating via callback does not cause the 500, but does not work, as stated initially

	$p->update([
		'palabras' => function($palabras) {
			return $palabras =  $palabras . ' , ' . $palabra;
		}
	], 'es');

…and yes, ‘palabras’ is the field’s name, and I assume that using $palabras get me the field’s content.

Thanks

There’s a syntax error:

return $palabras =  $palabras . ' , ' . $palabra,

Right, thank you.

Also… I can’t really do that, can I ? assigning in the return within the callback:

	page('oraculo')->update([
		'palabras' => function($palabras) {
			return $palabras =  $palabras . ' , ' . $palabra;
		}
	], 'es');

This should be correct I believe.

	page('oraculo')->update([
		'palabras' => function($palabras) {
			return $palabras . ' , ' . $palabra;
		}
	], 'es');

In any case calling the field as page function instead than as a variable worked for me:

	[
		'pattern' => '(:any)/oraculo',
		'method' => 'post',
		'action'  => function () {
			$palabra = get('palabra') ?? null;
			$recibir = get('recibir') ?? null;
			$p = page('oraculo');
			if ($palabra AND V::match($palabra, '/^([\pL])+$/u') AND V::maxWords($palabra, 1) AND V::maxLength($palabra, 27)) {
				$data = ['palabra_recibida' => true];
				$kirby = kirby();
				$kirby->impersonate('kirby');
				$p->update([
					'palabras' => $p->palabras() . ',' . $palabra
				], 'es');
			} elseif ($recibir) {
				$data = ['palabra_retornada' => true];
			} else {
				$data = ['error' => true];
			};
			return page('oraculo')->render($data);
		}
	],

Also, @pixelijn I do not need to return the modified page, I believe, as I modified a field in the page, and so re-rendering the page should have that into account right? I mean, the modified field will be echoed, as I changed the text file.

Thank you

Yes, looks like it; $page->update() | Kirby CMS

1 Like

Nevertheless @texnixe calling the content of the field as a variable within the callback function as it is shown on that example (and as I was trying to do originally) emtpies the field, it clears it, leaves it blank for some reason, what is wrong with this code? :

	$p->update([
		'palabras' => function($palabras) {
			return $palabras . ',' . $palabra;
		}
	], 'es');  

Actually the same happens if I call the field as page’s function within the callback:

	$p->update([
		'palabras' => function($palabras) {
			return $p->palabras() . ',' . $palabra;
		}
	], 'es');  

Why would that clean the field :thinking:

This is an extra question, I mark the original as solved nevertheless.

Thank you

I have never used a callback in conjunction with the update method, in fact, I didn’t even know this option existed :innocent:

But the reason why it doesn’t work is because if you use a callback, you have to pass your variable to the callback using the use statement.

$p->update([
		'palabras' => function($palabras) use($palabra) {
			return $palabras . ',' . $palabra;
		}
	], 'es');  

Oooh but of course… :man_facepalming:t4:

Thank you !