Skip to content

Commit

Permalink
Merge pull request #254 from ocftw/cms/pages/cards
Browse files Browse the repository at this point in the history
  • Loading branch information
ben196888 authored Oct 19, 2023
2 parents 5af2e3e + 2718084 commit 9333d5c
Show file tree
Hide file tree
Showing 15 changed files with 356 additions and 314 deletions.
28 changes: 28 additions & 0 deletions homepage/_pages/en/cards.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
unique_slug: cards
name: Cards
layout_list:
- type: layout_headline
title: Card Introduction
- type: layout_cards
card_type: project
title: Project Card | Open Government
card_tags:
- open gov
- type: layout_cards
title: Project Card | Open Data
card_type: project
card_tags:
- open data
- type: layout_cards
title: Project Card | Open Source
card_type: project
card_tags:
- open source
- type: layout_cards
title: Job Card
card_type: job
- type: layout_cards
title: Event Card
card_type: event
---
28 changes: 28 additions & 0 deletions homepage/_pages/zh-tw/cards.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
unique_slug: cards
name: 卡片頁
layout_list:
- type: layout_headline
title: 卡片介紹
- type: layout_cards
card_type: project
title: 專案卡 | 開放政府專案
card_tags:
- open gov
- type: layout_cards
title: 專案卡 | 開放資料專案
card_type: project
card_tags:
- open data
- type: layout_cards
title: 專案卡 | 開放原始碼專案
card_type: project
card_tags:
- open source
- type: layout_cards
title: 人力卡
card_type: job
- type: layout_cards
title: 事件卡
card_type: event
---
35 changes: 35 additions & 0 deletions homepage/src/components/cards.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { ParseMarkdownAndHtml } from './parseMarkdownAndHtml';

const Cards = ({ id, title, cards }) => {
return (
<div className="section" id={id}>
<div className="container">
<div className="section-head">
<h2>{title}</h2>
</div>
<div className="row">
{cards.map((card) => (
<Card key={card.data.id} card={card} />
))}
</div>
</div>
</div>
);
};

const Card = ({ card }) => (
<div className="col-md-4 mb-3" id={card.data.id}>
<div className="section-main">
<h3>{card.data.title}</h3>
<div>
<img src={card.data.image} alt={card.data.title} />
<strong>{card.data.description}</strong>
<ParseMarkdownAndHtml markdown={true}>
{card.content}
</ParseMarkdownAndHtml>
</div>
</div>
</div>
);

export default Cards;
87 changes: 18 additions & 69 deletions homepage/src/layouts/contentMapper.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,76 +4,25 @@ import ThreeColumns from '../components/threeColumns';
import ImageAndText from '../components/imageAndText';
import Section from '../components/section';
import Headline from '../components/headline';
import Cards from '../components/cards';
import { componentTypes } from '../lib/componentMapper';

const contentMapper = (layout) => {
switch (layout.type) {
case 'layout_banner':
return (
<Banner
key={layout.title}
id={layout.id}
title={layout.title}
subtitle={layout.subtitle}
heroImage={layout.hero_image}
highlights={layout.highlights}
/>
);
case 'layout_section':
if (layout.columns?.length === 2) {
return (
<TwoColumns
key={layout.title}
id={layout.id}
title={layout.title}
columns={layout.columns}
markdown={true}
/>
);
} else if (layout.columns?.length === 3) {
return (
<ThreeColumns
key={layout.title}
id={layout.id}
title={layout.title}
columns={layout.columns}
markdown={true}
/>
);
} else {
return (
<Section
key={layout.title}
id={layout.id}
title={layout.title}
subtitle={layout.columns?.[0]?.title}
image={layout.columns?.[0]?.image}
content={layout.columns?.[0]?.text}
markdown={true}
/>
);
}
case 'layout_image_text':
return (
<ImageAndText
key={layout.title}
id={layout.id}
image={layout.image}
title={layout.title}
subtitle={layout.subtitle}
content={layout.text}
highlights={layout.highlights}
markdown={true}
/>
);
case 'layout_headline':
return (
<Headline
key={layout.title}
id={layout.id}
title={layout.title}
subtitle={layout.subtitle}
/>
);
const contentMapper = (component) => {
switch (component.type) {
case componentTypes.Banner:
return <Banner key={component.id} {...component.props} />;
case componentTypes.Headline:
return <Headline key={component.id} {...component.props} />;
case componentTypes.ImageAndText:
return <ImageAndText key={component.id} {...component.props} />;
case componentTypes.OneColumn:
return <Section key={component.id} {...component.props} />;
case componentTypes.TwoColumns:
return <TwoColumns key={component.id} {...component.props} />;
case componentTypes.ThreeColumns:
return <ThreeColumns key={component.id} {...component.props} />;
case componentTypes.Cards:
return <Cards key={component.id} {...component.props} />;
default:
return null;
}
Expand Down
121 changes: 121 additions & 0 deletions homepage/src/lib/componentMapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { titleToAnchorId } from './titleToAnchorId';

const removeUndefined = (obj) => {
const newObj = {};
Object.keys(obj).forEach((key) => {
if (obj[key] !== undefined) {
newObj[key] = obj[key];
}
});
return newObj;
};

export const componentTypes = {
Banner: 'Banner',
Headline: 'Headline',
OneColumn: 'OneColumn',
TwoColumns: 'TwoColumns',
ThreeColumns: 'ThreeColumns',
ImageAndText: 'ImageAndText',
Cards: 'Cards',
};

export const componentMapper = (layout, cards = []) => {
let type = '';
let props = {};
switch (layout.type) {
case 'layout_banner': {
type = componentTypes.Banner;
props = {
id: titleToAnchorId(layout.title),
title: layout.title,
subtitle: layout.subtitle,
heroImage: layout.hero_image,
highlights: layout.highlights,
};
break;
}
case 'layout_headline': {
type = componentTypes.Headline;
props = {
id: titleToAnchorId(layout.title),
title: layout.title,
subtitle: layout.subtitle,
};
break;
}
case 'layout_image_text': {
type = componentTypes.ImageAndText;
props = {
id: titleToAnchorId(layout.title),
title: layout.title,
subtitle: layout.subtitle,
image: layout.image,
content: layout.text,
highlights: layout.highlights,
markdown: true,
};
break;
}
case 'layout_section': {
if (layout.columns?.length <= 1) {
type = componentTypes.OneColumn;
props = {
id: titleToAnchorId(layout.title),
title: layout.title,
subtitle: layout.columns?.[0]?.title,
image: layout.columns?.[0]?.image,
content: layout.columns?.[0]?.text,
markdown: true,
};
break;
} else if (layout.columns?.length === 2) {
type = componentTypes.TwoColumns;
props = {
id: titleToAnchorId(layout.title),
title: layout.title,
columns: layout.columns,
markdown: true,
};
break;
} else if (layout.columns?.length >= 3) {
type = componentTypes.ThreeColumns;
props = {
id: titleToAnchorId(layout.title),
title: layout.title,
columns: layout.columns,
markdown: true,
};
break;
}
}
case 'layout_cards': {
let filteredCards = cards;
// filter cards by card_type
if (layout.card_type) {
filteredCards = cards.filter(
(card) => layout.card_type === card.data.type,
);
}
// filter cards by card_tags
if (layout.card_tags && layout.card_tags.length > 0) {
filteredCards = filteredCards.filter((card) =>
layout.card_tags.every((tag) => card.data.tags?.includes(tag)),
);
}

type = componentTypes.Cards;
props = {
id: titleToAnchorId(layout.title),
title: layout.title,
cards: filteredCards,
};
break;
}
}

return {
type,
props: removeUndefined(props),
};
};
17 changes: 4 additions & 13 deletions homepage/src/lib/fetchCards.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ import fs from 'fs';
import { join } from 'path';
import matter from 'gray-matter';

import { remark } from 'remark';
import html from 'remark-html';

const cardsDirectory = join(process.cwd(), '_cards');

/**
Expand All @@ -16,24 +13,18 @@ function getCardDirectoryPath(lang) {
return join(cardsDirectory, lang);
}

export async function fetchCards(lang) {
export function fetchCards(lang) {
const cardsDirectory = getCardDirectoryPath(lang);
const filesInCards = fs.readdirSync(cardsDirectory);

const cards = filesInCards.map(async (filename) => {
const cards = filesInCards.map((filename) => {
const fullPath = join(cardsDirectory, filename);
const file = fs.readFileSync(fullPath, 'utf8');
const matterFile = matter(file);
const { data, content } = matterFile;

const processedContent = await remark().use(html).process(content);
const contentHtml = processedContent.toString();

return {
frontMatter: data,
content: contentHtml,
};
return { data, content };
});

return Promise.all(cards);
return cards;
}
5 changes: 0 additions & 5 deletions homepage/src/lib/fetchPage.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import fs from 'fs';
import { join } from 'path';
import matter from 'gray-matter';
import { titleToAnchorId } from './titleToAnchorId';

const pagesDirectory = join(process.cwd(), '_pages');

Expand All @@ -16,10 +15,6 @@ export function fetchPage(lang, page) {
const fileContent = fs.readFileSync(filePath, 'utf8');
const { data } = matter(fileContent);

data['layout_list']?.forEach((layout) => {
layout.id = layout.id || titleToAnchorId(layout.title);
});

return {
data,
};
Expand Down
6 changes: 0 additions & 6 deletions homepage/src/lib/getNavigationList.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ export async function getPagesList(lang) {

export async function getNavigationList(lang) {
const pagesList = await getPagesList(lang);
const cardsPage = {
en: 'Cards',
'zh-tw': '卡片頁',
};

// * dynamic page navigation
const navigationList = pagesList
Expand All @@ -41,8 +37,6 @@ export async function getNavigationList(lang) {
page.path = page.path.replace('index', '');
return { link: `/${page.path}`, text: page.name };
});
// add hard coded cards page
navigationList.push({ link: `/cards`, text: cardsPage[lang] });

return navigationList;
}
7 changes: 7 additions & 0 deletions homepage/src/lib/markdownToHtml.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { remark } from 'remark';
import html from 'remark-html';

export async function markdownToHtml(markdown) {
const result = await remark().use(html).process(markdown);
return result.toString();
}
Loading

0 comments on commit 9333d5c

Please sign in to comment.