I have the following custom field which fetches categories defined in site.txt.
<?php
class CategoryField extends SelectField {
public function __construct() {
$this->type = 'text';
$this->icon = 'chevron-down';
$this->label = 'Categories';
$this->options = array();
foreach(kirby()->site()->categories()->split() as $category) {
$this->options[$category] = $category;
}
}
}
While this works fine, I’d much rather define those categories in the parent page of the article where they are going to be used. Only, I can’t figure out how to address that parent page from the custom field. Any ideas?
Thx, Sonja
Have you tried, if you can get the page object with the following?
$page = $this->page();
// cause then you might be able to do:
foreach($this->page()->parent()->categories()->split() as $category) {
$this->options[$category] = $category;
}
It’s used it panel/apps/fields/tags/tags.php
- maybe that can help.
thx, @distantnative, I think I tried almost anything I could think of including your suggestion but nothing worked; well, I try again, maybe I just made some stupid mistake.
[Edit] No, the result is still the same, and I get an error message regarding the parent method; at least I would have thought that $this->page() would give me some sort of result because I have seen it being used in other fields …
@distantnative: you’re right,$this->page()
works, only not where I put it but within an input function, so I simply copied the select field like so and only added the options:
class CategoryField extends BaseField {
public function __construct() {
$this->type = 'select';
$this->icon = 'chevron-down';
$this->label = 'category';
$this->options = array();
}
public function options() {
return FieldOptions::build($this);
}
public function option($value, $text, $selected = false) {
return new Brick('option', $this->i18n($text), array(
'value' => $value,
'selected' => $selected
));
}
public function input() {
$select = new Brick('select');
$select->addClass('selectbox');
$select->attr(array(
'name' => $this->name(),
'id' => $this->id(),
'required' => $this->required(),
'autocomplete' => $this->autocomplete(),
'autofocus' => $this->autofocus(),
'readonly' => $this->readonly(),
'disabled' => $this->disabled(),
));
$select = $select->append($this->option('', '', $this->value() == ''));
if($this->readonly()) {
$select->attr('tabindex', '-1');
}
$categories = $this->page()->parent()->categories()->split();
foreach($categories as $category) {
$this->options[$category] = $category;
}
foreach($this->options() as $value => $text) {
$select->append($this->option($value, $text, $this->value() == $value));
}
$inner = new Brick('div');
$inner->addClass('selectbox-wrapper');
$inner->append($select);
$wrapper = new Brick('div');
$wrapper->addClass('input input-with-selectbox');
$wrapper->append($inner);
if($this->readonly()) {
$wrapper->addClass('input-is-readonly');
} else {
$wrapper->attr('data-focus', 'true');
}
return $wrapper;
}
public function validate() {
return array_key_exists($this->value(), $this->options());
}
}
This still leaves me with the problem, that the field cannot be saved in the panel and I haven’t figured out why, it always get a red border around it. Any ideas?
Are you sure that $this->options()
in the validate()
method still has your categories included?
You’re right, if I delete the validate() method, I can at least save the page though not sure if I should do that.