I'd like to create an entry in Craft that talks about a new discount, and then choose that discount via a field (so a bit like you can choose an entry or a product). That way, should the parameters of the discount change, I'm not having to manually update the information in the entry to match any changes to the discount details. Is there a plugin for this?

  • ^ I guess the same could apply to commerce subscriptions as well. By the way I'm using Craft 3 and Commerce 2.
    – KevAdamson
    Nov 13 '18 at 11:29

That field type doesn’t currently exist, but it wouldn’t be hard to create it.

Here’s the relevant code you’d need if you want to take a stab at it:

use Craft;
use craft\base\ElementInterface;
use craft\commerce\models\Discount;
use craft\commerce\Plugin as Commerce;

// ...

public function normalizeValue($value, ElementInterface $element = null)
    if ($value !== null) {
        return Commerce::getInstance()->discounts->getDiscountById($value);

    return $value;

public function getInputHtml($value, ElementInterface $element = null): string
    $options = [];
    foreach (Commerce::getInstance()->discounts->getAllDiscounts() as $discount) {
        $options[] = ['value' => $discount->id, 'label' => $discount->name];

    /** @var Discount|null $value */
    return Craft::$app->view->renderTemplate('_includes/forms/select', [
        'id' => $this->handle,
        'name' => $this->handle,
        'options' => $options,
        'value' => $value->id ?? null,

With that, the field type’s value would always either be a Discount model or null, so in your templates you could do this:

{% if entry.myDiscountField %}
    Code: <code>{{ entry.myDiscountField.code }}</code>
{% endif %}

Alternatively, you could pull this off with a simple Plain Text field that stores a discount code, and then fetch the discount manually from your template.

{% if entry.myDiscountCodeField %}
    {% set discount = craft.commerce.discounts.getDiscountByCode(entry.myDiscountCodeField) %}
{% else %}
    {% set discount = null %}
{% endif %}

{% if discount %}
    Code: <code>{{ discount.code }}</code>
{% endif %}
  • I am having a problem after create the discount field. When I try to save the entry with discount field, I got the error "Discount Field should contain at most 255 characters." I checked the code in the field, and commented out "normalizeValue" function. Or instead of commenting public function normalizeValue($value, ElementInterface $element = null) { if ($value !== null) { return Commerce::getInstance()->discounts->getDiscountById($value)->id; } return $value; } might be right? Jul 10 '19 at 1:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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