'viewBag', 'description' => 'Stores custom template properties.' ]; } public function validateProperties(array $properties) { return $properties; } public function __call($method, $parameters) { if (array_key_exists($method, $this->properties) && !method_exists($this, $method)) { return $this->properties[$method]; } return parent::__call($method, $parameters); } public function defineProperties() { $result = []; foreach ($this->properties as $name => $value) { $result[$name] = [ 'title' => $name, 'type' => 'string' ]; } return $result; } }