XHP: Basic Usage

First, make sure that you have the XHP Library installed a dependency of your project — this defines the various core classes of XHP, and the standard HTML components.

XHP is a syntax to create actual Hack objects, called XHP objects. They are meant to be used as a tree, where children can either be other XHP objects, or text nodes.

Creating a Simple XHP Object

Instead of using the new operator, creating XHP looks very much like XML:

$my_xhp_object = <p>Hello, world</p>;

$my_xhp_object now contains an instance of the :p class - the initial : marks it as an XHP class, but is not needed when instantiating it. It is a real object, meaning that is_object() will return true and you can call methods on it.

The following example utilizes three XHP classes: :div, :strong, :i. Whitespace is insignificant so you can create a readable tree structure in your code.

<?hh

function basic_usage_examples_basic_xhp(): void {
  var_dump(
    <div>
       My Text
       <strong>My Bold Text</strong>
       <i>My Italic Text</i>
    </div>
  );
}

basic_usage_examples_basic_xhp();
Output
object(xhp_div)#5 (5) {
  ["tagName":protected]=>
  string(3) "div"
  ["attributes":"xhp_x__composable_element":private]=>
  object(HH\Map)#6 (0) {
  }
  ["children":"xhp_x__composable_element":private]=>
  object(HH\Vector)#7 (3) {
    [0]=>
    string(9) " My Text "
    [1]=>
    object(xhp_strong)#12 (5) {
      ["tagName":protected]=>
      string(6) "strong"
      ["attributes":"xhp_x__composable_element":private]=>
      object(HH\Map)#13 (0) {
      }
      ["children":"xhp_x__composable_element":private]=>
      object(HH\Vector)#14 (1) {
        [0]=>
        string(12) "My Bold Text"
      }
      ["context":"xhp_x__composable_element":private]=>
      object(HH\Map)#15 (0) {
      }
      ["source"]=>
      string(91) "/data/users/joelm/user-documentation/guides/hack/24-XHP/02-basic-usage-examples/basic.php:9"
    }
    [2]=>
    object(xhp_i)#19 (5) {
      ["tagName":protected]=>
      string(1) "i"
      ["attributes":"xhp_x__composable_element":private]=>
      object(HH\Map)#20 (0) {
      }
      ["children":"xhp_x__composable_element":private]=>
      object(HH\Vector)#21 (1) {
        [0]=>
        string(14) "My Italic Text"
      }
      ["context":"xhp_x__composable_element":private]=>
      object(HH\Map)#22 (0) {
      }
      ["source"]=>
      string(92) "/data/users/joelm/user-documentation/guides/hack/24-XHP/02-basic-usage-examples/basic.php:10"
    }
  }
  ["context":"xhp_x__composable_element":private]=>
  object(HH\Map)#8 (0) {
  }
  ["source"]=>
  string(92) "/data/users/joelm/user-documentation/guides/hack/24-XHP/02-basic-usage-examples/basic.php:11"
}

The var_dump() shows that the a tree of objects has been created — not an HTML/XML string. An HTML string can be produced either by simply using echo/print(), or by calling $xhp_obect->toString().

Dynamic Content

The examples so far have only shown static content, but usually you'll need to include something that's generated at runtime; for this, you can use Hack expressions directly within XHP with curly braces:

<xhp_class>{$some_expression}</xhp_class>

This also works for attributes:

<xhp_class attribute={$some_expression} />

More complicated expressions are also supported, for example:

<?hh

class MyBasicUsageExampleClass {
  public function getInt(): int {
    return 4;
  }
}

function basic_usage_examples_get_string(): string {
  return "Hello";
}

function basic_usage_examples_get_float(): float {
  return 1.2;
}

function basic_usage_examples_embed_hack(): void {
  $xhp_float = <i>{basic_usage_examples_get_float()}</i>;
  $a = new MyBasicUsageExampleClass();

  echo (
    <div>
      {(new MyBasicUsageExampleClass())->getInt()}
      <strong>{basic_usage_examples_get_string()}</strong>
      {$xhp_float /* this embeds the <i /> element as a child of the <div /> */}
    </div>
  );
}

basic_usage_examples_embed_hack();
Output
<div>4<strong>Hello</strong><i>1.2</i></div>

Attributes

Like HTML, XHP supports attributes on an XHP object. An XHP object can have zero to an unlimited number of attributes available to it. The XHP class defines what attributes are available to objects of that class.

echo <input type="button" name="submit" value="OK" />;

Here the :input class has the attributes type, name and value as part of its class properties.

Some attributes are required, and XHP will throw an error if you use an XHP object with a required attribute without the attribute.

HTML Character References

In order to encode a reserved HTML character or a character that is not readily available to you, you can use HTML character references in XHP.

<?hh
echo <span>&hearts; &#9829; &#x2665;</span>;

The above uses HTML character reference encoding to print out the heart symbol using the explicit name, decimal notation and hex notation.