# Converting a Project to XHP

DevFeed: [Converting a Project to XHP](<https://devfeed.tech/articles/converting-a-project-to-xhp-22044.md>)

Original publisher: [Read original article](<https://codebeforethehorse.tumblr.com/post/87306947716>)

Author: Codebeforethehorse

Published: 2014-05-30T16:15:00Z

Content type: tutorial

Language: en

Sources: [Stefan Parker](<https://devfeed.tech/sources/stefan-parker.md>)

Topics: [Refactoring](<https://devfeed.tech/topics/refactoring.md>), [XSS](<https://devfeed.tech/topics/xss.md>), [Code](<https://devfeed.tech/topics/code.md>), [HTML](<https://devfeed.tech/topics/html.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [html](<https://devfeed.tech/tags/html.md>), [refactoring](<https://devfeed.tech/tags/refactoring.md>), [xhp](<https://devfeed.tech/tags/xhp.md>), [xss](<https://devfeed.tech/tags/xss.md>)

## AI overview

This tutorial explains how to migrate a project from HTML strings to XHP by wrapping selected raw HTML in marker objects and modifying XHP's child rendering and validation internals. It also argues against using automatic regex conversion because it could perpetuate HTML-string usage.

## Source excerpt

Unless you're starting from scratch, using XHP is most likely going to take some refactoring of old HTML-as-string code. The problem is that because of XHP's auto-escaping to prevent XSS holes, you can't include strings of HTML as children into XHP elements. Fortunately there's something you can do to allow XHP to ignore certain strings and return them directly as HTML. This is essentially what Facebook had to do when we started converting our entire codebase into XHP in 2009. First off, you'll need a marker for strings that should be ignored by XHP. The best way to do this is to create an object that holds the strings and you can easily do instanceof checks on it. Let's call this object HTML (protip: objects and classes exist in different contexts, so they can have the same name without problem). class HTML { private $htmlString; public function __construct($htmlString) { $this->htmlString = $htmlString; } public function getRawHTML() { return $this->htmlString; } } function HTML($htmlString) { return new HTML($htmlString); } Now we'll need to adjust XHP's internals in two places to check for the existence of HTML objects: when rendering children and when validating children. The first location will be inside :xhp:renderChild(). The method looks like this: final protected static function renderChild($child) { if ($child instanceof :xhp) { return $child->__toString(); } else if (is_array($child)) { throw new XHPRenderArrayException('Can not render array!'); } else { return htmlspecialchars((string)$child); } } You'll need to add a check into this block for your HTML instances. Best place is right after your check for :xhp, since that should be the most common. final protected static function renderChild($child) { if ($child instanceof :xhp) { return $child->__toString(); } else if ($child instanceof HTML) { return $child->getRawHTML(); } else if (is_array($child)) { throw new XHPRenderArrayException('Can not render array!'); } else { return htmlspecialchars((string)