Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert the CAPI Multiple PaidFor template to Svelte #347

Merged
merged 26 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a8dd0e2
Initial commit for capi multiple paidfor migration
emma-imber Dec 20, 2023
5ece4b1
Add extra preview mode
emma-imber Dec 20, 2023
0fe8591
Add logo to bottom right of container
emma-imber Dec 20, 2023
c3e08a6
Remove unused BrandLogo variable
emma-imber Dec 22, 2023
dc68be1
Mobile style updates
emma-imber Jan 2, 2024
8d34319
Add media icons
emma-imber Jan 2, 2024
d571392
Consolidate Capi Card logic into one component
emma-imber Jan 3, 2024
454edba
Update sponsor logo styling
emma-imber Jan 3, 2024
15ae30f
Align title
emma-imber Jan 3, 2024
f78e8a2
Finessing margins and padding
emma-imber Jan 3, 2024
d031e25
Use live campaign
emma-imber Jan 3, 2024
dfd7b5d
Fix mobile header styles
emma-imber Jan 3, 2024
f4d11a0
Change how we do the kicker
emma-imber Jan 3, 2024
47e19d8
Fix single header
emma-imber Jan 3, 2024
fc62bf7
Add icons to title if specific media type
emma-imber Jan 4, 2024
749263c
Update capiMultiple to work with new GAMVariable type
emma-imber Jan 4, 2024
ce99528
Lint
emma-imber Jan 4, 2024
95b51eb
More specific type
emma-imber Jan 5, 2024
524aa6a
Don't use GAMVariable type in PaidForHeader
emma-imber Jan 5, 2024
5d47d44
Use Svelte class directive
emma-imber Jan 5, 2024
fe5dcc1
Await formatted cards in one request and check that response is defined
emma-imber Jan 5, 2024
4e79257
Lint
emma-imber Jan 5, 2024
358332e
Delete unused variables
emma-imber Jan 8, 2024
4c0a10c
Narrower templateType types
emma-imber Jan 8, 2024
a1c09a0
Add colour change on hover
emma-imber Jan 8, 2024
25712ed
Add ad json
emma-imber Jan 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/lib/Previews.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
].join('');

export const widths = {
1300: 'desktop',
1300: 'wide',
980: 'desktop',
740: 'tablet',
360: 'mobile',
};
Expand Down
33 changes: 33 additions & 0 deletions src/lib/capiMultiple.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import type { GAMVariable } from './gam';
import type { CapiCardOverride, Single } from './types/capi';

const apiEndpoint =
'https://api.nextgen.guardianapps.co.uk/commercial/api/capi-multiple.json';

function addHeadlineKicker(
overrideCards: CapiCardOverride[],
cardData: Single[],
) {
for (let i = 0; i < overrideCards.length; i++) {
if (overrideCards[i]?.kicker && overrideCards[i]?.headline) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- headline should always be defined
cardData[i]!.articleHeadline = overrideCards[i]?.headline as string;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- we define the kicker here - it's an optional parameter
cardData[i]!.kicker = overrideCards[i]?.kicker as string;
}
}

return cardData;
}

function retrieveCapiData(cards: CapiCardOverride[], seriesUrl: GAMVariable) {
let request = `${apiEndpoint}?k=${encodeURI(seriesUrl)}`;
cards.forEach((card) => {
if (card.url) {
request += `&t=${encodeURI(card.url)}`;
}
});
return fetch(request).then((response) => response.json());
}

export { retrieveCapiData, addHeadlineKicker };
10 changes: 10 additions & 0 deletions src/lib/types/capi.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { GAMVariable } from '$lib/gam';

export type Source = {
minWidth: string;
sizes: string;
Expand Down Expand Up @@ -44,4 +46,12 @@ export type Single = {
galleryTag: boolean;
videoTag: boolean;
branding: Branding;
kicker?: string;
};

export type CapiCardOverride = {
headline: GAMVariable;
image: GAMVariable;
url: GAMVariable;
kicker: GAMVariable;
};
151 changes: 130 additions & 21 deletions src/templates/components/CapiCard.svelte
Original file line number Diff line number Diff line change
@@ -1,16 +1,33 @@
<script lang="ts">
import type { Single } from '$lib/types/capi';
import Sponsor from './Sponsor.svelte';
import AudioIcon from './icons/AudioIcon.svelte';
import CameraIcon from './icons/CameraIcon.svelte';
import VideoIcon from './icons/VideoIcon.svelte';

export let templateType: 'single' | 'multiple';
export let single: Single;
export let direction = 'row';

const { articleHeadline, articleUrl, articleText, articleImage } = single;
const {
articleHeadline,
articleUrl,
articleText,
articleImage,
audioTag,
galleryTag,
videoTag,
kicker,
} = single;
const pictureSupported =
articleImage.sources.length > 0 && 'srcset' in new Image();
</script>

<a href={articleUrl} style={`--direction: ${direction}`}>
<a
class="{templateType}-card"
href={articleUrl}
style={`--direction: ${direction}`}
>
<div class="media">
{#if pictureSupported}
<picture>
Expand All @@ -34,27 +51,66 @@
{/if}
</div>
<div class="text">
<h2>{articleHeadline}</h2>
<p>{articleText}</p>
<h2>
{#if kicker}
<span class="kicker">{kicker && kicker}</span><br />
{/if}
{#if audioTag}
<AudioIcon />
{:else if galleryTag}
<CameraIcon />
{:else if videoTag}
<VideoIcon />
{/if}
{articleHeadline}
</h2>
{#if templateType === 'single'}
<p>{articleText}</p>
{/if}
</div>
<Sponsor branding={single.branding} />
{#if templateType === 'single'}
<Sponsor branding={single.branding} />
{/if}
</a>

<style>
<style lang="scss">
a {
color: #000000;
text-decoration: none;
color: inherit;
}

a.single-card {
display: grid;
gap: 20px;
padding: 10px;
}

.media {
a.multiple-card {
margin: 12px 10px 0px 10px;
display: block;
padding: 0 0 8px 0;
width: auto;
background-color: #f6f6f6;
border-top: 1px solid #69d1ca;
}

a.multiple-card:not(:first-of-type)::before {
content: '';
position: absolute;
top: 119px;
bottom: 102px;
margin-left: -10px;
width: 1px;
background: #dcdcdc;
}

a.single-card .media {
margin: -10px;
}

.text {
padding: 0;
a.multiple-card .media {
background-color: gray;
margin: 0;
}

picture,
Expand All @@ -63,32 +119,85 @@
width: 100%;
}

h2 {
margin: 0;
padding: 0 0 10px;
font-size: 1.25rem;
a.single-card .text {
padding: 0;

h2 {
margin: 0;
padding: 0 0 10px;
font-size: 1.25rem;
}

p {
display: none;
margin: 0;
padding: 0;
}
}

p {
display: none;
margin: 0;
padding: 0;
a.multiple-card .text {
padding: 0 5px;

h2 {
font-size: 1rem;
line-height: 1.25rem;
font-family: 'GuardianTextSans', 'Helvetica Neue', Helvetica, Arial,
'Lucida Grande', sans-serif;
font-weight: 500;
padding: 0px;
margin: 6px 0 8px 0;
color: #333;
}
}

.kicker {
color: #626262;
}

:global(svg.icon) {
fill: #767676;
height: 0.7em;
width: 1.2em;
line-height: inherit;
margin-right: 0.1em;
}

@media (max-width: 739px) {
a.multiple-card:not(:first-of-type) .media {
display: none;
}
}

@media (min-width: 740px) {
a {
a.single-card {
grid-template-columns: 1fr 1fr;
grid-template-rows: repeat(2, auto);
}

.media {
a.single-card .media {
grid-row: span 2;
}

a.multiple-card {
margin: 12px 10px;
}

a.multiple-card:nth-child(n) {
display: block;
}

a.multiple-card .text h2 {
margin-bottom: 10px;
}
}

@media (min-width: 1140px) {
.text p {
a.single-card .text p {
display: block;
}

a.multiple-card:not(:first-of-type)::before {
top: 12px;
}
}
</style>
Loading
Loading