Skip to content

Commit

Permalink
Merge pull request #144 from Financial-Times/matth/refactor-teaser-rules
Browse files Browse the repository at this point in the history
Refactor teaser rules
  • Loading branch information
i-like-robots authored Aug 24, 2018
2 parents a439878 + fb922de commit cd9db7d
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 39 deletions.
26 changes: 14 additions & 12 deletions components/x-teaser/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,24 @@ Teasers display _content_ but our content items are also decorated with hints an

### Rules

Because there are so many [teaser properties](#properties) some options can conflict. In these cases one option must take precedence over the others. These sitations are resolved by using a _ruleset_. A ruleset is an array of functions ordered by importance. The first function in the array to return a truthy value wins and the name of the matching function will be returned.
Because there are so many [teaser properties](#properties) some options can conflict. In these cases one option must take precedence over the others. These sitations are resolved by using a _ruleset_. A ruleset is a function which implements a series of conditions in order of precedence. When a condition evaluates to true it must return.

For example to decide which media type to display (a video, headshot, or image) we define the following ruleset:

```js
const media = [
function video(props) {
return props.showVideo && props.video;
},
function headshot(props) {
return props.showHeadshot && props.headshot && props.indicators.isColumn;
},
function image(props) {
return props.showImage && props.image;
}
];
const media = (props) => {
if (props.showVideo && props.video && props.video.url) {
return 'video';
}

if (props.showHeadshot && props.headshot && props.headshot.url && props.indicators.isColumn) {
return 'headshot';
}

if (props.showImage && props.image && props.image.url) {
return 'image';
}
};
```

## Usage
Expand Down
55 changes: 28 additions & 27 deletions components/x-teaser/src/concerns/rules.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,35 @@
/**
* Rules are collections of exclusive properties. They are declared in a ruleset
* (an array of functions) in order of precedence. Each value returned by a rule
* will evaluated as a boolean and the name of any matching rule returned.
* Rules are sets of exclusive properties.
* They are used to ensure that only one property can take precedence.
*/
const rulesets = {
media: [
function video(props) {
return props.showVideo && props.video && props.video.url;
},
function headshot(props) {
return (
props.showHeadshot && props.headshot && props.headshot.url && props.indicators.isColumn
);
},
function image(props) {
return props.showImage && props.image && props.image.url;
media: (props) => {
// If this condition evaluates to true then no headshot nor image will be displayed.
if (props.showVideo && props.video && props.video.url) {
return 'video';
}
],
theme: [
function live(props) {
return props.status && props.status === 'inprogress';
},
function opinion(props) {
return props.indicators && props.indicators.isOpinion;
},
function highlight(props) {
return props.indicators && props.indicators.isEditorsChoice;

if (props.showHeadshot && props.headshot && props.headshot.url && props.indicators.isColumn) {
return 'headshot';
}

if (props.showImage && props.image && props.image.url) {
return 'image';
}
]
},
theme: (props) => {
if (props.status && props.status === 'inprogress') {
return 'live'
}

if (props.indicators && props.indicators.isOpinion) {
return 'opinion'
}

if (props.indicators && props.indicators.isEditorsChoice) {
return 'highlight'
}
}
};

/**
Expand All @@ -38,8 +40,7 @@ const rulesets = {
*/
export default function rules(rule, props) {
if (rulesets.hasOwnProperty(rule)) {
const index = rulesets[rule].findIndex((rule) => rule(props));
return index !== -1 ? rulesets[rule][index].name : null;
return rulesets[rule](props);
} else {
throw Error(`No ruleset available named ${rule}`);
}
Expand Down

0 comments on commit cd9db7d

Please sign in to comment.