Casting with ArrayData

Silverstripe Version:
4.1

Question:
How can I cast an ArrayData element when doing renderWith inside my controller

Details of your query go here
I am doing a renderWith inside my PageController. How can I cast ‘Title’ to be HTMLText?

$Data = new ArrayData ( array(
	'Segment' => $segment,
	'Tag' => $tag,
	'Audience' => $audience_segment,
	'Title' => $title . " ‘". Convert::raw2xml($tagtitle) . "’",
	'FilterTitle' => $filtertitle,
	'Items' => $paginatedItems,
	'Audiences' => $audiencelist,
	'AudienceCount' => $audience_count
));

return $this->customise($Data)->renderWith(array($template, 'Page'));

I figured it out.

<?php
use SilverStripe\View\ArrayData;

class TagPageData extends ArrayData {
    private static $casting = array(
        'Title' => 'HTMLText'
    );
}
....
$Data = new TagPageData ( array(
    'Segment' => $segment,
    'Tag' => $tag,
    'Audience' => $audience_segment,
    'Title' => $title . " &lsquo;". Convert::raw2xml($tagtitle) . "&rsquo;",
    'FilterTitle' => $filtertitle,
    'Items' => $paginatedItems,
    'Audiences' => $audiencelist,
    'AudienceCount' => $audience_count
));
            
return $this->customise($Data)->renderWith(array($template, 'Page'));

Neat solution, I didn’t realise $casting could be used on ArrayData. Just FYI, you can also cast on the fly by passing in a DBField object instead of a string:

$htmlTitle = $title . " &lsquo;". Convert::raw2xml($tagtitle) . "&rsquo;";
return $this->renderWith([$template, 'Page'], [
	'Title' => DBField::create_field('HTMLText', $htmlTitle),
	...
]);

Yeah I’d agree with @JonoM - it seems a little elaborate to subclass ArrayData just for casting

A nicer solution. Thank you

Wouldn’t Title.RAW in the template work?

Of course there’s the potential xss if your Title field contains scripts; but casting wouldn’t help then either. As far as i could tell the scripts are removed at entry via tinymce, not on output