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.
require __DIR__."/../../../../vendor/hh_autoload.php";
<<__EntryPoint>>
function basic_usage_examples_basic_xhp(): void {
var_dump(
<div>
My Text
<strong>My Bold Text</strong>
<i>My Italic Text</i>
</div>,
);
}
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 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_object->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 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:
require __DIR__."/../../../../vendor/hh_autoload.php";
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;
}
<<__EntryPoint>>
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>
);
}
<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 or any 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 but 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>♥ ♥ ♥</span>;
The above uses HTML character reference encoding to print out the heart symbol using the explicit name, decimal notation, and hex notation.