Twigマクロの戻り値に注意! Twig\Markup型と演算エラーの落とし穴
2025-05-19
2分で読了
更新: 2025-12-27
目次
Craft CMSでテンプレートを組んでいると、「マクロ便利だな〜」と思う場面、多いですよね。
たとえば、税抜価格を取得するためにこんなマクロを定義していたとします。
{% macro getPrice(totalPrice, taxRate) %}
{{ totalPrice / (1 + taxRate) }}
{% endmacro %}
このマクロを使って、税抜価格を数値として扱いたい場合、以前は以下のように書いても普通に動いていました。
{{ _self.getPrice(order.totalPrice, taxRate)|trim * 1 }}
しかし、ある日 Craft CMS をアップデートしたら突然こんなエラーが出るように...。
Unsupported operand types: Twig\Markup * int
原因:Twig\Markup型のままでは演算できない
このエラーの原因は、_self.getPrice() の戻り値が「単なる数値」ではなく Twig\Markup オブジェクトになっていることです。
実は {{ }} で囲まれた中身は Twig内部で「HTMLとして安全な文字列」として扱うために Twig\Markup というクラスでラップされます。だから、見た目は数値でも中身は「HTML的な何か」なんですね。
試しに普通に出力した場合とDumpした場合を見てみると下図のようになっています。

対処法:明示的に文字列化してから数値化する
Twig\Markup 型をそのまま * 1 のように計算に使うとエラーになります。
そこで、まず string フィルタで文字列に変換しましょう。
{{ _self.getPrice(order.totalPrice, taxRate)|string|trim * 1 }}
こうすることで、
|stringでTwig\Markupを文字列に変換|trimで余計な空白を除去* 1で文字列を数値にキャスト(JavaScriptの* 1と同じ発想)
という流れになります。
いつからこの挙動になった?
正確なバージョンは定かではありませんが、Craft CMS 4.x + Twig 3系以降で {{ ... }} の出力が Twig\Markup になる挙動が強化されたようです。
参考になれば幸いです。