Comments (5)
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.
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.
@everton-rosario would you be able to give @m4olivei some guidance? Thanks!
from facebook-instant-articles-sdk-php.
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.
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)
- Failed Connection with graph.facebook.com HOT 2
- Handling of Ads Settings fields
- Support paragraphs inside Blockquote
- FAN on AMP? HOT 2
- Validate Analytics Configuration
- Installation problem on laravel 5.6 HOT 1
- RTL problem HOT 2
- Unable to use ConstantGetter with InteractiveRule HOT 4
- autoplay video in fullscreen HOT 1
- Transformer's transform method does not account for settings
- Problem in rule "multiple" - IA HOT 3
- Query params in related articles
- [BUG] : Problem with the Span and Anchor Rule
- Travis CI Php 5.5 and Php 5.4
- Fetch
- Integration in Symfony 5 is not possible because of css selector version in composer.json HOT 1
- FBInterstitialAd is gives all time "server error"
- support php 8 HOT 2
- Use InstantArticleInterface instead of InstantArticle as parameter type for Transformer methods
- How to create a scheduled facebook instant article through PHP SDK
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from facebook-instant-articles-sdk-php.