4

I have created a fieldtype that saves a single integer to the database, it has some settings that defines the maximum value that integer can be:

protected function defineSettings()
{
  return array(
    'maxNumber' => array(AttributeType::Number, 'min' => 2, 'default' => 12)
  );
}

What I want to do when outputting my field in the templates is something like this:

The value is {{ entry.myField }} of {{ entry.myField.maxNumber }}

Anyone have any ideas? Do I need to create a data class like the options-based fields use or something? I'm just stabbing around in the dark here...

2 Answers 2

7

Like plugins, fieldtypes can have their own settings as you're aware but while you can grab your plugin settings from pretty much anywhere, fieldtypes are a little more contextual.

In any case, like @Bryan pointed out, your fieldtype needs to implement prepValue($value) and ideally return a model containing the value as defined in defineAttributes() and the maxNumber as a property.

This basically means that when Craft calls your fieldtype's prepValue($value) which it does when the value of your field is needed (editing/outputting) you can return a model with the value and maxNumber.


EDIT:

// MyFieldType.php
public function prepValue($value)
{
    $model = new MyFieldModel;

    $model->setAttribute('value', $value);
    $model->setMaxNumber($this->getSettings()->getAttribute('maxNumber'));

    return $model;
}
// MyFieldModel.php
// Explicit getter/setter for $maxNumber rather than defining it as an attribute
protected $maxNumber;

public function setMaxNumber($value)
{
    $this->maxNumber = $value;
}

public function getMaxNumber()
{
    return $this->maxNumber;
}

public function defineAttributes()
{
    return array(
        'value' => AttributeType::Number,
    );
}
// _entry.html or other template name
{{ entry.myFieldHandle.value }}
{{ entry.myFieldHandle.maxNumber }}

@selvinortiz

14
  • Great thanks Selvin! Where would the field model live? In the actual models directory or in the fieldtypes one? Commented Jun 19, 2014 at 14:56
  • In the models directory so that craft can autoload it for you. Commented Jun 19, 2014 at 15:01
  • It would be in models. @Selvin, I would be concerned about not returning a number with the __toString. Wouldn't __invoke be preferred so you can return it as the right type? Commented Jun 19, 2014 at 15:01
  • Thanks @SelvinOrtiz - I'll have a look tomorrow and let you know how I get on! Commented Jun 19, 2014 at 15:02
  • @Bryan if __toString() is a concern then @Josh can implement a getValue() method on the model and use it as {{ entry.myField.value }} which I would prefer over __invoke() since there is enough magic happening in Yii already. Commented Jun 19, 2014 at 15:04
1

To do this as you describe, you would need to add the prepValue function to your field type. You would then need to create a PHP class to fill with your field value and settings.

I'm not sure that it would work, but I also suggest adding the __invoke() method. You could use it to return the field value when you use the object as a variable (though Twig would call it as a method I think).

1
  • Could you expand a bit on how the php class part would work? I did end up trying that and basing my code of the OptionsData class but couldn't for the life of me work out how to use it - Yii didn't seem to know about my class when I called it like so new MyPlugin_FieldTypeData Commented Jun 19, 2014 at 14:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.