Skip to content

Commit 49abb13

Browse files
authored
Add GraphQL support for term meta (#281)
1 parent 7bef8be commit 49abb13

File tree

3 files changed

+126
-12
lines changed

3 files changed

+126
-12
lines changed

DOCUMENTATION.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ If you wish to change this to `summary`, you can [publish the SEO Pro config](#p
168168

169169
## GraphQL
170170

171-
If you're accessing content through Statamic's [GraphQL API](https://statamic.dev/graphql], you can render SEO meta this way as well. For example, in an [entries query](https://statamic.dev/graphql#entries-query) you can access prerendered SEO meta `html` under `seo`:
171+
If you're accessing content through Statamic's [GraphQL API](https://statamic.dev/graphql], you can render SEO meta on your entries and terms this way as well. For example, in an [entries query](https://statamic.dev/graphql#entries-query) you can access prerendered SEO meta `html` under `seo`:
172172

173173
```graphql
174174
{

src/ServiceProvider.php

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,19 +164,22 @@ protected function bootAddonGraphQL()
164164
GraphQL::addType(\Statamic\SeoPro\GraphQL\SeoProType::class);
165165
GraphQL::addType(\Statamic\SeoPro\GraphQL\AlternateLocaleType::class);
166166

167-
GraphQL::addField('EntryInterface', 'seo', function () {
167+
$seoField = function () {
168168
return [
169169
'type' => GraphQL::type('SeoPro'),
170-
'resolve' => function ($entry, $args) {
170+
'resolve' => function ($item) {
171171
return (new Cascade)
172172
->with(SiteDefaults::load()->augmented())
173-
->with($this->getAugmentedSectionDefaults($entry))
174-
->with($entry->seo)
175-
->withCurrent($entry)
173+
->with($this->getAugmentedSectionDefaults($item))
174+
->with($item->seo)
175+
->withCurrent($item)
176176
->get();
177177
},
178178
];
179-
});
179+
};
180+
181+
GraphQL::addField('EntryInterface', 'seo', $seoField);
182+
GraphQL::addField('TermInterface', 'seo', $seoField);
180183

181184
return $this;
182185
}

tests/GraphQLTest.php

Lines changed: 116 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22

33
namespace Tests;
44

5-
use Illuminate\Support\Carbon;
65
use Statamic\Facades\Collection;
7-
use Statamic\Facades\Entry;
6+
use Statamic\Facades\Data;
87

98
class GraphQLTest extends TestCase
109
{
@@ -15,6 +14,7 @@ protected function getEnvironmentSetup($app)
1514
$app['config']->set('statamic.editions.pro', true);
1615
$app['config']->set('statamic.graphql.enabled', true);
1716
$app['config']->set('statamic.graphql.resources.collections', true);
17+
$app['config']->set('statamic.graphql.resources.taxonomies', true);
1818
$app['config']->set('statamic.seo-pro.assets.container', 'assets');
1919
}
2020

@@ -24,14 +24,14 @@ public function setUp(): void
2424

2525
$this
2626
->setSeoInSiteDefaults([
27+
'site_name' => 'Cool Runnings',
2728
'priority' => 0.7,
2829
])
2930
->setSeoOnCollection(Collection::find('articles'), [
30-
'site_name' => 'Cool Runnings',
3131
'site_name_position' => 'before',
3232
'site_name_separator' => '>>>',
3333
])
34-
->setSeoOnEntry(Entry::findByUri('/nectar'), [
34+
->setSeoOnEntry(Data::findByUri('/nectar'), [
3535
'image' => 'img/stetson.jpg',
3636
]);
3737
}
@@ -153,7 +153,118 @@ public function it_queries_for_entry_seo_cascade_so_user_can_render_custom_meta(
153153
'url' => '/assets/img/stetson.jpg',
154154
'permalink' => 'http://cool-runnings.com/assets/img/stetson.jpg',
155155
],
156-
'last_modified' => Carbon::today()->format('Y-m-d'),
156+
'last_modified' => Data::findByUri('/nectar')->lastModified()->format('Y-m-d'),
157+
],
158+
],
159+
]]);
160+
}
161+
162+
/** @test */
163+
public function it_queries_for_term_seo_meta_html()
164+
{
165+
$query = <<<'GQL'
166+
{
167+
term(id: "topics::dance") {
168+
title
169+
seo {
170+
html
171+
}
172+
}
173+
}
174+
GQL;
175+
176+
$expectedHtml = collect([
177+
'<title>Dance | Cool Runnings</title>',
178+
'<meta property="og:type" content="website" />',
179+
'<meta property="og:title" content="Dance" />',
180+
'<meta property="og:url" content="http://cool-runnings.com/topics/dance" />',
181+
'<meta property="og:site_name" content="Cool Runnings" />',
182+
'<meta property="og:locale" content="en_US" />',
183+
'<meta name="twitter:card" content="summary_large_image" />',
184+
'<meta name="twitter:title" content="Dance" />',
185+
'<link href="http://cool-runnings.com/" rel="home" />',
186+
'<link href="http://cool-runnings.com/topics/dance" rel="canonical" />',
187+
'<link type="text/plain" rel="author" href="http://cool-runnings.com/humans.txt" />',
188+
])->implode('');
189+
190+
$this
191+
->withoutExceptionHandling()
192+
->post('/graphql', ['query' => $query])
193+
->assertGqlOk()
194+
->assertExactJson(['data' => [
195+
'term' => [
196+
'title' => 'Dance',
197+
'seo' => [
198+
'html' => $expectedHtml,
199+
],
200+
],
201+
]]);
202+
}
203+
204+
/** @test */
205+
public function it_queries_for_term_seo_cascade_so_user_can_render_custom_meta()
206+
{
207+
$query = <<<'GQL'
208+
{
209+
term(id: "topics::dance") {
210+
title
211+
seo {
212+
site_name
213+
site_name_position
214+
site_name_separator
215+
title
216+
compiled_title
217+
description
218+
priority
219+
change_frequency
220+
og_title
221+
canonical_url
222+
alternate_locales {
223+
url
224+
}
225+
prev_url
226+
next_url
227+
home_url
228+
humans_txt
229+
twitter_card
230+
twitter_handle
231+
image {
232+
url
233+
permalink
234+
}
235+
last_modified(format: "Y-m-d")
236+
}
237+
}
238+
}
239+
GQL;
240+
241+
$this
242+
->withoutExceptionHandling()
243+
->post('/graphql', ['query' => $query])
244+
->assertGqlOk()
245+
->assertExactJson(['data' => [
246+
'term' => [
247+
'title' => 'Dance',
248+
'seo' => [
249+
'site_name' => 'Cool Runnings',
250+
'site_name_position' => 'after',
251+
'site_name_separator' => '|',
252+
'title' => 'Dance',
253+
'compiled_title' => 'Dance | Cool Runnings',
254+
'description' => null,
255+
'priority' => 0.7,
256+
'change_frequency' => 'monthly',
257+
'og_title' => 'Dance',
258+
'canonical_url' => 'http://cool-runnings.com/topics/dance',
259+
'alternate_locales' => [],
260+
'prev_url' => null,
261+
'next_url' => null,
262+
'home_url' => 'http://cool-runnings.com/',
263+
'humans_txt' => 'http://cool-runnings.com/humans.txt',
264+
'twitter_card' => 'summary_large_image',
265+
'twitter_handle' => null,
266+
'image' => null,
267+
'last_modified' => Data::findByUri('/topics/dance')->lastModified()->format('Y-m-d'),
157268
],
158269
],
159270
]]);

0 commit comments

Comments
 (0)