Facebook Instant Articles PHP SDK - Elements

Elements

The Elements component of this SDK is a domain-specific language for creating an Instant Articles structure that strictly follows the specification and can be automatically serialized into the subset of HTML markup used in the Instant Articles format. This language allows users to programmatically create Instant Articles that are guaranteed to be in compliance with the format.


Elements is the object tree class that represents the structure of an Instant Article. This object tree structure ensures that no invalid Instant Article HTML markup is generated.


Example

Here is a simple and complete object tree structure, starting with the InstantArticle class that holds the full Instant Article.

$fragment = $document->createDocumentFragment();
$fragment->appendXML(
    '<h1>Some custom code</h1>'.
    '<script>alert("test");</script>'
);
$article =
    InstantArticle::create()
        ->withCanonicalUrl('http://foo.com/article.html')
        ->withHeader(
            Header::create()
                ->withTitle('Big Top Title')
                ->withSubTitle('Smaller SubTitle')
                ->withPublishTime(
                    Time::create(Time::PUBLISHED)
                        ->withDatetime(
                            \DateTime::createFromFormat(
                                'j-M-Y G:i:s',
                                '14-Aug-1984 19:30:00'
                            )
                        )
                )
                ->withModifyTime(
                    Time::create(Time::MODIFIED)
                        ->withDatetime(
                            \DateTime::createFromFormat(
                                'j-M-Y G:i:s',
                                '10-Feb-2016 10:00:00'
                            )
                        )
                )
                ->addAuthor(
                    Author::create()
                        ->withName('Author Name')
                        ->withDescription('Author more detailed description')
                )
                ->addAuthor(
                    Author::create()
                        ->withName('Author in FB')
                        ->withDescription('Author user in facebook')
                        ->withURL('http://facebook.com/author')
                )
                ->withKicker('Some kicker of this article')
                ->withCover(
                    Image::create()
                        ->withURL('https://jpeg.org/images/jpegls-home.jpg')
                        ->withCaption(
                            Caption::create()
                                ->appendText('Some caption to the image')
                        )
                )
                ->withSponsor(
                    Sponsor::create()
                        ->withPageUrl('http://facebook.com/my-sponsor')
                )
        )
        // Paragraph1
        ->addChild(
            Paragraph::create()
                ->appendText('Some text to be within a paragraph for testing.')
        )
        // Paragraph2
        ->addChild(
            Paragraph::create()
                ->appendText('Other text to be within a second paragraph for testing.')
        )
        // Slideshow
        ->addChild(
            SlideShow::create()
                ->addImage(
                    Image::create()
                        ->withURL('https://jpeg.org/images/jpegls-home.jpg')
                )
                ->addImage(
                    Image::create()
                        ->withURL('https://jpeg.org/images/jpegls-home2.jpg')
                )
                ->addImage(
                    Image::create()
                        ->withURL('https://jpeg.org/images/jpegls-home3.jpg')
                )
        )
        // Paragraph3
        ->addChild(
            Paragraph::create()
                ->appendText('Some text to be within a paragraph for testing.')
        )
        // Ad
        ->addChild(
            Ad::create()
                ->withSource('http://foo.com')
        )
        // Paragraph4
        ->addChild(
            Paragraph::create()
                ->appendText('Other text to be within a second paragraph for testing.')
        )
        // Analytics
        ->addChild(
            Analytics::create()
                ->withHTML($fragment)
        )
        // Footer
        ->withFooter(
            Footer::create()
                ->withCredits('Some plaintext credits.')
        );

Rendering the InstantArticle Markup

From above, $article now contains a complete InstantArticle object — a structured representation of an Instant Article — which can be rendered into valid Instant Article HTML Markup by simply calling its render() function:

$article->render('<!doctype html>');

The rendered output of the InstantArticle object from above is:

<!doctype html>
<html>
<head>
    <link rel="canonical" href="http://foo.com/article.html"/>
    <meta charset="utf-8"/>
    <meta property="op:markup_version" content="v1.0"/>
    <meta property="fb:use_automatic_ad_placement" content="true"/>
</head>
<body>
    <article>
        <header>
            <figure>
                <img src="https://jpeg.org/images/jpegls-home.jpg"/>
                <figcaption>Some caption to the image</figcaption>
            </figure>
            <h1>Big Top Title</h1>
            <h2>Smaller SubTitle</h2>
            <time class="op-published" datetime="1984-08-14T19:30:00+00:00">August 14th, 7:30pm</time>
            <time class="op-modified" datetime="2016-02-10T10:00:00+00:00">February 10th, 10:00am</time>
            <address>
                <a>Author Name</a>
                Author more detailed description
            </address>
            <address>
                <a href="http://facebook.com/author" rel="facebook">Author in FB</a>
                'Author user in facebook'.
            </address>
            <h3 class="op-kicker">Some kicker of this article</h3>
            <ul class="op-sponsors">
                <li>
                    <a href="http://facebook.com/my-sponsor" rel="facebook"></a>
                </li>
            </ul>
        </header>
        <p>Some text to be within a paragraph for testing.</p>
        <p>Other text to be within a second paragraph for testing.</p>
        <figure class="op-slideshow">
            <figure>
                <img src="https://jpeg.org/images/jpegls-home.jpg"/>
            </figure>
            <figure>
                <img src="https://jpeg.org/images/jpegls-home2.jpg"/>
            </figure>
            <figure>
                <img src="https://jpeg.org/images/jpegls-home3.jpg"/>
            </figure>
        </figure>
        <p>Some text to be within a paragraph for testing.</p>
        <figure class="op-ad">
            <iframe src="http://foo.com"></iframe>
        </figure>
        <p>Other text to be within a second paragraph for testing.</p>
        <figure class="op-tracker">
            <iframe>
                <h1>Some custom code</h1>
                <script>alert("test");</script>
            </iframe>
        </figure>
        <footer>
            <aside>Some plaintext credits.</aside>
        </footer>
    </article>
</body>
</html>