Giter Site home page Giter Site logo

How do you use the PullquoteRule and PullquoteCiteRule classes to put together a pull quote with a cite? about facebook-instant-articles-sdk-php HOT 5 CLOSED

facebook avatar facebook commented on April 26, 2024
How do you use the PullquoteRule and PullquoteCiteRule classes to put together a pull quote with a cite?

from facebook-instant-articles-sdk-php.

Comments (5)

everton-rosario avatar everton-rosario commented on April 26, 2024 1

Here is a snippet of the rules configuration json that have your markup covered.
Please check if it works for you.
I've also added a test case under PullquoteRuleTest.php.

   ...
    {
        "class": "TextNodeRule"
    },
    {
        "class": "ItalicRule",
        "selector": "em"
    },
    {
        "class": "ParagraphRule",
        "selector": "p"
    },
    {
        "class": "PassThroughRule",
        "selector": "div.field-quote > p"
    },
    {
        "class": "PassThroughRule",
        "selector" : "div.field-quote"
    },
    {
        "class" : "PullquoteRule",
        "selector" : "blockquote.pull-quote"
    },
    {
        "class" : "PullquoteCiteRule",
        "selector" : "div.field-quote-author"
    }
    ...

from facebook-instant-articles-sdk-php.

m4olivei avatar m4olivei commented on April 26, 2024 1

Yeah, that would be good, documenting the why's. Also more examples with source markup, transformer rules, and destination markup.

Another thing that would be good is to flesh out your custom Rule example. I ended up figuring it out, but it was tricky. Here's my example, and maybe there are a series of out of the box transformer rules that could do this:

Source markup (eg. http://www.bravotv.com/blogs/local-regional-chains-we-miss-from-our-hometowns-wawa-carvel-skyline)

<h2 class="listicle">
  <span class="listicle__number">1</span><span class="listicle__title">Carvel</span>
</h2>

Target markup:

<h2>1. Caravel</h2>

So this annoying need to get a ". " in there between the number and the title itself. Ended up writing this custom rule for it:

<?php

/**
 * @file
 * Class definition of ListicleRule.
 */

use Facebook\InstantArticles\Elements\H2;
use Facebook\InstantArticles\Elements\InstantArticle;
use Facebook\InstantArticles\Transformer\Rules\ConfigurationSelectorRule;
use Facebook\InstantArticles\Transformer\Transformer;
use Facebook\InstantArticles\Transformer\Warnings\InvalidSelector;

/**
 * Class ListicleRule.  Transforms Listicle markup to markup appropriate for
 * Facebook Instant Articles.
 */
class ListicleRule extends ConfigurationSelectorRule  {

  const PROPERTY_NUMBER = 'listicle.number';
  const PROPERTY_TITLE = 'listicle.title';

  /**
   * {@inheritdoc}
   */
  public function getContextClass() {
    return array(InstantArticle::class);
  }

  /**
   * Create an instant of ListicleRule.
   * @return \ListicleRule
   */
  public static function create() {
    return new ListicleRule();
  }

  /**
   * Create an instance from a transformer rules configuration array.
   *
   * @param array $configuration
   * @return \ListicleRule
   */
  public static function createFrom($configuration) {
    $rule = self::create();
    $rule->withSelector($configuration['selector']);

    $rule->withProperties(
      array(
        self::PROPERTY_NUMBER,
        self::PROPERTY_TITLE,
      ),
      $configuration
    );

    return $rule;
  }

  /**
   * Apply the transformation from Listicle to FB Instant Articles markup.
   *
   * @param Transformer $transformer
   * @param InstantArticle $instant_article
   * @param DOMElement $node
   * @return mixed
   */
  public function apply($transformer, $instant_article, $node) {
    $number = $this->getProperty(self::PROPERTY_NUMBER, $node);
    $title = $this->getProperty(self::PROPERTY_TITLE, $node);
    $h2 = H2::create();

    if ($title) {
      if ($number) {
        $h2->appendText($number . '. ' . $title);
      }
      else {
        $h2->appendText($title);
      }
      $instant_article->addChild($h2);
    }
    else {
      $transformer->addWarning(
        new InvalidSelector(
          'title',
          $instant_article,
          $node,
          $this
        )
      );
    }

    return $instant_article;
  }
}

And finally, here is the rule config:

/** @var \Facebook\InstantArticles\Transformer\Transformer $transformer */
// Transform Listicle
$listicle_config = array(
  'class' => 'ListicleRule',
  'selector' => '.listicle',
  'properties' => array(
    'listicle.number' => array(
      'type' => 'string',
      'selector' => '.listicle__number',
    ),
    'listicle.title' => array(
      'type' => 'string',
      'selector' => '.listicle__title',
    ),
  ),
);
$listicle_rule = ListicleRule::createFrom($listicle_config);
$transformer->addRule($listicle_rule);

The most confusing, undocumented part for me was figuring out how the properties worked. It's super cleaver how it works, what with the Getters and all, but until you wrap your head around the Getters, it's all very magical and confusing. Here all I needed was type => 'string', which uses the StringGetter, which is pretty straightforward after you know about it, the other getters are even more confusing though.

I also ended up needing to write a custom Getter. Admittedly, maybe this is getting into major edge case land, but I'll tell you about it anyway in case it helps the education effort. Our web articles have images throughout, and each image is a derivative of the giant source image (responsive images, yay).

<picture>
  <!--bunch of srcset tags--->
  <!--fallback img--->
  <img src="http://www.bravotv.com/sites/nbcubravotv/files/styles/blog-post--computer/public/the-feast-regional-chains-carvel.jpg?itok=3DKQrLSK" alt="" title="" />
</picture>

So http://www.bravotv.com/sites/nbcubravotv/files/styles/blog-post--computer/public/the-feast-regional-chains-carvel.jpg is the derivative image, and http://www.bravotv.com/sites/nbcubravotv/files/the-feast-regional-chains-carvel.jpg is the source. I wanted to have the source image in the Instant Articles feed, so you guys could have all the pixels at your disposal. There were a bunch of different approaches that I tried, but in the end, I wrote a custom Getter to work with the ImageRule. Here's the custom Getter:

<?php

/**
 * @file
 * Contains Drupal\FBInstantArticles\ScrSetImageStyleGetter
 */

use Facebook\InstantArticles\Transformer\Getters\StringGetter;

/**
 * Custom Facebook Instant Articles SDK 'Getter'.  Extend the simple
 * StringGetter, but add some processing to strip any descriptors and change
 * the URL to the original image from an image style.
 */
class SrcSetImageStyleGetter extends StringGetter {
  /**
   * {@inheritdoc}
   */
  public function get($node) {
    $srcset = parent::get($node);

    // Trim off any images past the first
    $srcset = explode(',', $srcset);
    $srcset = $srcset[0];
    preg_match('~^(?:.(?!\d+[w|x]))+~', $srcset, $matches);
    $url = $matches[0];

    // Turn an image style URL into the src image.
    return preg_replace('~styles/.*?/public/~', '', $url);
  }
}

Paired with this rule:

// Find <picture><img /><picture> constructs and turn them into Image
// elements.  Uses a custom Getter, to take a srcset attribute that has an
// image style on it and change it to the original image.
$picture_config = array(
  'class' => 'ImageRule',
  'selector' => '//p[picture[img]]',
  'properties' => array(
    'image.url' => array(
      'type' => 'SrcSetImageStyleGetter',
      'selector' => 'img',
      'attribute' => 'srcset',
    ),
    'image.caption' => array(
      'type' => 'element',
      'selector' => 'img[@alt]',
    ),
  ),
);
$image_rule = ImageRule::createFrom($picture_config);
$transformer->addRule($image_rule);

It works nicely, and didn't require that I change the rendering of our web articles at all, but it took a lot to figure out.

So yeah, I think more education about the Rules and Getters and when you might use them, ie the limitations of the out of the box stuff, would be helpful.

from facebook-instant-articles-sdk-php.

simonengelhardt avatar simonengelhardt commented on April 26, 2024

@everton-rosario would you be able to give @m4olivei some guidance? Thanks!

from facebook-instant-articles-sdk-php.

m4olivei avatar m4olivei commented on April 26, 2024

Totally works. I've got a better understanding of the Transformer now as a result of this example. The Transformer has been a difficult thing to wrap my head around. There has been much xdebug-ing to better understand it, and this example helped with that too. Thanks a bunch!

from facebook-instant-articles-sdk-php.

everton-rosario avatar everton-rosario commented on April 26, 2024

We are working to make it as simple as possible.
The problem is complex and too wide (markup interpreting/transforming).

Maybe better docs and some "why's" of architecture decisions would make it easier to extend.

If you have any other feedback regarding this, let me know.

from facebook-instant-articles-sdk-php.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.