How do you use the PullquoteRule and PullquoteCiteRule classes to put together a pull quote with a cite? #18
Comments
@everton-rosario would you be able to give @m4olivei some guidance? Thanks! |
Here is a snippet of the rules configuration json that have your markup covered. ...
{
"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"
}
... |
Closes #18 - Add test to cover and document a different Pullquote markup
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! |
We are working to make it as simple as possible. 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. |
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 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).
So <?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. |
I'm using the Transformer. My target markup is this:
How do I use
PullquoteRule
and/orPullquoteCiteRule
to transform to this:At least it seems like
PullquoteRule
class is missing a property for the attribution?The text was updated successfully, but these errors were encountered: