Skip to content

Commit dad289c

Browse files
osiuxMichaelDeBoey
andauthored
feat(Pinterest): Add support for Pinterest (#73)
* Support Pinterest * Update tests Co-authored-by: Michaël De Boey <info@michaeldeboey.be>
1 parent ed6f881 commit dad289c

File tree

7 files changed

+195
-4
lines changed

7 files changed

+195
-4
lines changed

README.md

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@
2020

2121
Trying to embed well known services (like [CodePen][codepen],
2222
[CodeSandbox][codesandbox], [GIPHY][giphy], [Instagram][instagram],
23-
[Lichess][lichess], [Slides][slides], [SoundCloud][soundcloud],
24-
[Spotify][spotify], [Streamable][streamable], [Twitter][twitter] or
25-
[YouTube][youtube]) into your [Gatsby][gatsby] website can be hard, since you
26-
have to know how this needs to be done for all of these different services.
23+
[Lichess][lichess], [Pinterest][pinterest], [Slides][slides],
24+
[SoundCloud][soundcloud], [Spotify][spotify], [Streamable][streamable],
25+
[Twitter][twitter] or [YouTube][youtube]) into your [Gatsby][gatsby] website can
26+
be hard, since you have to know how this needs to be done for all of these
27+
different services.
2728

2829
## This solution
2930

@@ -45,6 +46,7 @@ and replace it with the proper embed-code.
4546
- [GIPHY](#giphy)
4647
- [Instagram](#instagram)
4748
- [Lichess](#lichess)
49+
- [Pinterest](#pinterest)
4850
- [Slides](#slides)
4951
- [SoundCloud](#soundcloud)
5052
- [Spotify](#spotify)
@@ -304,6 +306,34 @@ https://instagram.com/p/B60jPE6J8U-
304306

305307
</details>
306308

309+
### Pinterest
310+
311+
The returned HTML snippet from the Pinterest transformer will only be
312+
automatically recognized as an embedded pin when Pinterest's embed JavaScript is
313+
included on the page.
314+
Since the Pinterest transformer doesn't include this JavaScript (because we
315+
don't want to include it multiple times on a page when having multiple embeds),
316+
you have to include it yourself. The recommended way of including it is by using
317+
[`gatsby-plugin-pinterest`][gatsby-plugin-pinterest].
318+
319+
#### Usage
320+
321+
```md
322+
https://pinterest.com/pin/99360735500167749
323+
```
324+
325+
<details>
326+
<summary><b>Result</b></summary>
327+
328+
```html
329+
<a
330+
data-pin-do="embedPin"
331+
href="https://pinterest.com/pin/99360735500167749"
332+
></a>
333+
```
334+
335+
</details>
336+
307337
### Lichess
308338

309339
#### Usage
@@ -661,11 +691,13 @@ MIT
661691
[embedded-tweet-docs]: https://developer.twitter.com/web/embedded-tweets
662692
[gatsby]: https://github.com/gatsbyjs/gatsby
663693
[gatsby-plugin-instagram-embed]: https://github.com/jlengstorf/gatsby-plugin-instagram-embed
694+
[gatsby-plugin-pinterest]: https://github.com/robinmetral/gatsby-plugin-pinterest
664695
[gatsby-plugin-twitter]: https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-twitter
665696
[giphy]: https://giphy.com
666697
[instagram]: https://instagram.com
667698
[kentcdodds.com-repo]: https://github.com/kentcdodds/kentcdodds.com
668699
[lichess]: https://lichess.org
700+
[pinterest]: https://pinterest.com
669701
[slides]: https://slides.com
670702
[soundcloud]: https://soundcloud.com
671703
[spotify]: https://spotify.com

src/__tests__/__fixtures__/kitchensink.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ https://instagram.com/p/B60jPE6J8U-
2727

2828
https://lichess.org/MPJcy1JW
2929

30+
https://pinterest.com/pin/99360735500167749
31+
3032
https://slides.com/kentcdodds/oss-we-want
3133

3234
https://soundcloud.com/clemenswenners/africa

src/__tests__/plugin.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ describe('gatsby-remark-embedder', () => {
5353
5454
<iframe src=\\"https://lichess.org/embed/MPJcy1JW\\" width=\\"600\\" height=\\"397\\" frameborder=\\"0\\"></iframe>
5555
56+
<a data-pin-do=\\"embedPin\\" href=\\"https://pinterest.com/pin/99360735500167749\\"></a>
57+
5658
<iframe src=\\"https://slides.com/kentcdodds/oss-we-want/embed\\" width=\\"576\\" height=\\"420\\" scrolling=\\"no\\" frameborder=\\"0\\" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
5759
5860
<iframe width=\\"100%\\" height=\\"300\\" scrolling=\\"no\\" frameborder=\\"no\\" src=https://w.soundcloud.com/player?url=https://soundcloud.com/clemenswenners/africa&color=ff5500&auto_play=false&hide_related=true&show_comments=true&show_user=true&show_reposts=false&show_teaser=false&visual=true></iframe>
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import cases from 'jest-in-case';
2+
3+
import plugin from '../..';
4+
import { getHTML, shouldTransform } from '../../transformers/Pinterest';
5+
6+
import { cache, getMarkdownASTForFile, parseASTToMarkdown } from '../helpers';
7+
8+
cases(
9+
'url validation',
10+
({ url, valid }) => {
11+
expect(shouldTransform(url)).toBe(valid);
12+
},
13+
{
14+
'non-Pinterest url': {
15+
url: 'https://not-a-pinterest-url.com',
16+
valid: false,
17+
},
18+
"non-Pinterest url ending with 'pinterest.com'": {
19+
url: 'https://this-is-not-pinterest.com',
20+
valid: false,
21+
},
22+
"non-Pinterest url ending with 'pinterest.com' and having '/pin/' in the url": {
23+
url: 'https://this-is-not-pinterest.com/pin/99360735500167749',
24+
valid: false,
25+
},
26+
'board url': {
27+
url: 'https://pinterest.com/pinterest/official-news',
28+
valid: true,
29+
},
30+
"board url having 'www' subdomain": {
31+
url: 'https://www.pinterest.com/pinterest/official-news',
32+
valid: true,
33+
},
34+
'pin url': {
35+
url: 'https://pinterest.com/pin/99360735500167749',
36+
valid: true,
37+
},
38+
"pin url having 'www' subdomain": {
39+
url: 'https://www.pinterest.com/pin/99360735500167749',
40+
valid: true,
41+
},
42+
'profile url': {
43+
url: 'https://pinterest.com/pinterest',
44+
valid: true,
45+
},
46+
"profile url having 'www' subdomain": {
47+
url: 'https://www.pinterest.com/pinterest',
48+
valid: true,
49+
},
50+
}
51+
);
52+
53+
test('Gets the correct Pinterest board link', () => {
54+
const html = getHTML('https://pinterest.com/pinterest/official-news');
55+
56+
expect(html).toMatchInlineSnapshot(
57+
`"<a data-pin-do=\\"embedBoard\\" data-pin-board-width=\\"400\\" data-pin-scale-height=\\"240\\" data-pin-scale-width=\\"80\\" href=\\"https://pinterest.com/pinterest/official-news\\"></a>"`
58+
);
59+
});
60+
61+
test('Gets the correct Pinterest pin link', () => {
62+
const html = getHTML('https://pinterest.com/pin/99360735500167749');
63+
64+
expect(html).toMatchInlineSnapshot(
65+
`"<a data-pin-do=\\"embedPin\\" href=\\"https://pinterest.com/pin/99360735500167749\\"></a>"`
66+
);
67+
});
68+
69+
test('Gets the correct Pinterest profile link', () => {
70+
const html = getHTML('https://pinterest.com/pinterest');
71+
72+
expect(html).toMatchInlineSnapshot(
73+
`"<a data-pin-do=\\"embedUser\\" data-pin-board-width=\\"400\\" data-pin-scale-height=\\"240\\" data-pin-scale-width=\\"80\\" href=\\"https://pinterest.com/pinterest\\"></a>"`
74+
);
75+
});
76+
77+
test('Plugin can transform Pinterest links', async () => {
78+
const markdownAST = getMarkdownASTForFile('Pinterest');
79+
80+
const processedAST = await plugin({ cache, markdownAST });
81+
82+
expect(parseASTToMarkdown(processedAST)).toMatchInlineSnapshot(`
83+
"<https://not-a-pinterest-url.com>
84+
85+
<https://this-is-not-pinterest.com>
86+
87+
<https://this-is-not-pinterest.com/pin/99360735500167749>
88+
89+
<a data-pin-do=\\"embedBoard\\" data-pin-board-width=\\"400\\" data-pin-scale-height=\\"240\\" data-pin-scale-width=\\"80\\" href=\\"https://pinterest.com/pinterest/official-news\\"></a>
90+
91+
<a data-pin-do=\\"embedBoard\\" data-pin-board-width=\\"400\\" data-pin-scale-height=\\"240\\" data-pin-scale-width=\\"80\\" href=\\"https://www.pinterest.com/pinterest/official-news\\"></a>
92+
93+
<a data-pin-do=\\"embedPin\\" href=\\"https://pinterest.com/pin/99360735500167749\\"></a>
94+
95+
<a data-pin-do=\\"embedPin\\" href=\\"https://www.pinterest.com/pin/99360735500167749\\"></a>
96+
97+
<a data-pin-do=\\"embedUser\\" data-pin-board-width=\\"400\\" data-pin-scale-height=\\"240\\" data-pin-scale-width=\\"80\\" href=\\"https://pinterest.com/pinterest\\"></a>
98+
99+
<a data-pin-do=\\"embedUser\\" data-pin-board-width=\\"400\\" data-pin-scale-height=\\"240\\" data-pin-scale-width=\\"80\\" href=\\"https://www.pinterest.com/pinterest\\"></a>
100+
"
101+
`);
102+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
https://not-a-pinterest-url.com
2+
3+
https://this-is-not-pinterest.com
4+
5+
https://this-is-not-pinterest.com/pin/99360735500167749
6+
7+
https://pinterest.com/pinterest/official-news
8+
9+
https://www.pinterest.com/pinterest/official-news
10+
11+
https://pinterest.com/pin/99360735500167749
12+
13+
https://www.pinterest.com/pin/99360735500167749
14+
15+
https://pinterest.com/pinterest
16+
17+
https://www.pinterest.com/pinterest

src/transformers/Pinterest.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { URL } from 'url';
2+
3+
import { getTrimmedPathName } from './utils';
4+
5+
const isPin = pathname => pathname.includes('pin/');
6+
const isProfile = pathname => pathname.split('/').length === 1;
7+
const isBoard = pathname => pathname.split('/').length === 2;
8+
9+
export const shouldTransform = url => {
10+
const { host, pathname } = new URL(url);
11+
const trimmedPathName = getTrimmedPathName(pathname);
12+
13+
return (
14+
['pinterest.com', 'www.pinterest.com'].includes(host) &&
15+
(isPin(trimmedPathName) ||
16+
isProfile(trimmedPathName) ||
17+
isBoard(trimmedPathName))
18+
);
19+
};
20+
21+
export const getHTML = url => {
22+
const { pathname } = new URL(url);
23+
const trimmedPathName = getTrimmedPathName(pathname);
24+
25+
if (isPin(trimmedPathName)) {
26+
return `<a data-pin-do="embedPin" href="${url}"></a>`;
27+
}
28+
29+
if (isBoard(trimmedPathName)) {
30+
return `<a data-pin-do="embedBoard" data-pin-board-width="400" data-pin-scale-height="240" data-pin-scale-width="80" href="${url}"></a>`;
31+
}
32+
33+
return `<a data-pin-do="embedUser" data-pin-board-width="400" data-pin-scale-height="240" data-pin-scale-width="80" href="${url}"></a>`;
34+
};

src/transformers/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as CodeSandboxTransformer from './CodeSandbox';
33
import * as GIPHYTransformer from './GIPHY';
44
import * as InstagramTransformer from './Instagram';
55
import * as LichessTransformer from './Lichess';
6+
import * as PinterestTransformer from './Pinterest';
67
import * as SlidesTransformer from './Slides';
78
import * as SoundCloudTransformer from './SoundCloud';
89
import * as SpotifyTransformer from './Spotify';
@@ -16,6 +17,7 @@ export const defaultTransformers = [
1617
GIPHYTransformer,
1718
InstagramTransformer,
1819
LichessTransformer,
20+
PinterestTransformer,
1921
SlidesTransformer,
2022
SoundCloudTransformer,
2123
SpotifyTransformer,

0 commit comments

Comments
 (0)