HTML() function is not recognized in PHP 5.3 #18

Closed
mjhca opened this Issue Nov 22, 2010 · 4 comments

Projects

None yet

3 participants

@mjhca
mjhca commented Nov 22, 2010

HTML() does not seem to be recognized (PHP 5.3.3 and XHP):

echo <div>{HTML('foo')}</div>;

Fatal error: Call to undefined function HTML()

@Swahvay
Collaborator
Swahvay commented Mar 16, 2012

This was a Facebook-specific function. Where are you seeing references to it in the code?

@mjhca
mjhca commented Mar 16, 2012

Swahvay, I don't understand your question. HTML() is documented XHP function. See the documentation here on the Wiki under "Escaping".

@carbonphyber

@Swahvay The HTML function (which you mention is FB-internal) is mentioned in:

  • The wiki for this repo https://github.com/facebook/xhp/wiki in both "escaping" and "best practices",
  • The source comments (the function is mentioned twice in core.php and the HTML class is inferred twice -- search for instanceof HTML in core.php), and
  • The original Facebook Engineering blog article (probably less of an issue since it's a few years old now).

Perhaps the public distribution of the code should not have mentions of the HTML function/class so as not to confuse developers external to Facebook.

@mjhca The HTML(...) function seems to be highly discouraged in all of the documentation for this project.

Common use-cases

You should stick to the expected methods of including non-tag text (called PCData in the XML world):

  • PHP string literal
<?php
echo <p>Copyright 2012, me</p>;
  • PHP variable string
<?php
echo <p>Copyright {date("Y")}, me</p>;
  • PHP variable string (another variant)
<?php
$copyright_statement = 'Copyright ' . date("Y") . ', me';
echo <p>{$copyright_statement}</p>;

My assumption is that your echos should entirely deal with instances of :x:composable-element and never with raw strings. My understanding of XHP is that you should be forced to write your own class that would return a string (from either the render or stringify method... depending on which class you extend). See my example code below.

More advanced use-case

I am experimenting with Markdown and BBCode (both are parsers that that translate user-generated content into HTML markup and escape the content that is not valid in their syntaxes) within an XHP wrapper. My test code follows.

I'm testing/evaluating XHP with [https://github.com/chobie/php-sundown](PHP-Sundown project) (a Markdown parser ported to PHP). Since the Markdown parser is escaping all user-generated content, I created an XHP class :

<?php
/**
 * @author David Wortham <https://github.com/carbonphyber/>
 * @license Creative Commons - Attribution 3.0 Unported <http://creativecommons.org/licenses/by/3.0/>
 * Example code is usable if you abide by the license above.
 */

/**
 * Custom ":djw" pseudo-namespace for all of my XHP classes
 * I would normally extend "x:element", but it seems for returning a PHP (string), ":x:primitive" is a better choice
 */
class :djw:markdown extends :x:primitive {
    /**
     * VERY IMPORTANT.  Without this line, this XHP class can not be a child of any ":html-element"
     */
    category %flow;
    /**
     * my user-generated content will be supplied via child PCData rather than XML-attributes
     */
    children (pcdata)*;

    /**
     * We override the "stringify" function for :x:primitive class instances.
     * If this was an instance of :x:element, we would override the "render" function instead
     * @access protected
     * @return (string) The string representation of this <djw:markdown> element (this will be used by the PHP __toString magic method on all :djw:markdown elements)
     */
    protected function stringify() {
        // gather the PCData / string representation of the children (to be used as \Sundown\Markdown input)
        $buf = implode('', $this->getChildren());
        if(empty($buf)) {
            // don't waste cycles on parsing if there's nothing to parse
            return '';
        }

        try {
            // build a new \Sundown\Markdown parer object using my custom decorator and configuration
            $md = new \Sundown\Markdown(new \DJW\Markdown(), array(
                'fenced_code_blocks' => TRUE,
            ));
            // render the Markdown; "stringify" should return a (string)
            return $md->render($buf);
        } catch(Exception $ex) {
            // this try/catch is not needed but I haven't researched how the \Sundown\Markdown render method handles error cases
            return '(markdown err0r)';
        }
    }
}

To echo the markup as part of an XHP-DOMtree:

<?php
$ugc = empty($_POST['markdown_content']) ? 'POST something and I will mark it up using Markdown' : $_POST['markdown_content'];
echo <x:doctype>
        <html>
            <head>{...}</head>
            <body>
                <h1>Rendered Markdown</h1>
                <djw:markdown>{$ugc}</djw:markdown>
            </body>
        </html>
    </x:doctype>;
@Swahvay Swahvay was assigned Feb 12, 2013
@Swahvay
Collaborator
Swahvay commented Apr 2, 2014
@Swahvay Swahvay closed this Apr 2, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment