Skip to content
This repository was archived by the owner on Jul 6, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Binary file added src/images/headshots/ben-ogorek.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/headshots/maria-juaristi.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/posts/obbba-household-by-household.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 31 additions & 14 deletions src/pages/BlogPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,25 +49,29 @@ export default function BlogPage() {
// /uk/research/blog-slug-here
const { postName } = useParams();
const countryId = useCountryId();
const [content, setContent] = useState("");

const post = posts.find((post) => post.slug === postName);
const postDate = formatFullDate(moment(post.date), countryId);

const imageUrl = post.image ? handleImageLoad(post.image) : "";
const file = require(`../posts/articles/${post.filename}`);
const isNotebook =
post && post.filename ? post.filename.endsWith(".ipynb") : false;
const file =
post && post.filename
? require(`../posts/articles/${post.filename}`)
: null;

const [content, setContent] = useState("");
const isNotebook = post.filename.endsWith(".ipynb");
useEffect(() => {
fetch(file)
.then((response) => response.text())
.then((text) => {
if (isNotebook) {
setContent(JSON.parse(text));
} else {
setContent(text);
}
});
if (file) {
fetch(file)
.then((response) => response.text())
.then((text) => {
if (isNotebook) {
setContent(JSON.parse(text));
} else {
setContent(text);
}
});
}
}, [file, isNotebook]);

// Some old links might point to a dated URL format
Expand All @@ -76,6 +80,19 @@ export default function BlogPage() {
return <Navigate to={`/${countryId}/blog/${postName.substring(11)}`} />;
}

// Handle external URL redirects
if (post && post.external_url) {
return <Navigate to={post.external_url} replace />;
}

// Handle missing post or filename
if (!post || !post.filename) {
return <Navigate to={`/${countryId}/research`} replace />;
}

const postDate = formatFullDate(moment(post.date), countryId);
const imageUrl = post.image ? handleImageLoad(post.image) : "";

let markdown;

if (isNotebook && content) {
Expand Down
4 changes: 2 additions & 2 deletions src/pages/home/HomeBlogPreview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -403,8 +403,8 @@ export function FeaturedBlogPreview({ blogs, width, imageHeight }) {
export function MediumBlogPreview({ blog, minHeight }) {
const displayCategory = useDisplayCategory();
const countryId = useCountryId();
const slug = blog.filename.split(".")[0];
const link = `/${countryId}/research/${slug}`;
const slug = blog.filename ? blog.filename.split(".")[0] : blog.slug;
const link = blog.external_url || `/${countryId}/research/${slug}`;

const imageUrl = blog.image ? handleImageLoad(blog.image) : "";

Expand Down
18 changes: 18 additions & 0 deletions src/posts/authors.json
Original file line number Diff line number Diff line change
Expand Up @@ -150,5 +150,23 @@
"github": "https://github.com/eccuraa",
"headshot": "elena-cura.png",
"title": "Data Science Intern at PolicyEngine"
},
"ben-ogorek": {
"name": "Ben Ogorek",
"email": "ben.ogorek@policyengine.org",
"bio": "Ben is a data scientist at PolicyEngine.",
"linkedin": "https://www.linkedin.com/in/benogorek/",
"github": "https://github.com/baogorek",
"headshot": "ben-ogorek.jpeg",
"title": "Data Scientist at PolicyEngine"
},
"maria-juaristi": {
"name": "Maria Juaristi",
"email": "maria@policyengine.org",
"bio": "Maria is a data scientist at PolicyEngine.",
"linkedin": "https://www.linkedin.com/in/mariajuaristi/",
"github": "https://github.com/juaristi22",
"headshot": "maria-juaristi.jpeg",
"title": "Data Scientist at PolicyEngine"
}
}
10 changes: 9 additions & 1 deletion src/posts/postTransformers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@ import posts from "./posts.json";
const postsSorted = posts.sort((a, b) => (a.date < b.date ? 1 : -1));

for (let post of postsSorted) {
post.slug = post.filename.substring(0, post.filename.indexOf("."));
if (post.filename) {
post.slug = post.filename.substring(0, post.filename.indexOf("."));
} else if (post.external_url) {
// For external URLs, generate a slug from the title
post.slug = post.title
.toLowerCase()
.replace(/\s+/g, "-")
.replace(/[^a-z0-9-]/g, "");
}
}

const tags = postsSorted.map((post) => post.tags);
Expand Down
18 changes: 16 additions & 2 deletions src/posts/posts.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,25 @@
{
"title": "Enhanced CPS full launch: Comprehensive microdata for policy analysis",
"description": "The Enhanced Current Population Survey now includes tip, overtime, and auto loan interest imputations, plus upcoming state and congressional district calibration.",
"date": "2025-08-08",
"date": "2025-08-11",
"tags": ["us", "data", "featured"],
"filename": "enhanced-cps-launch.md",
"image": "enhanced-cps-launch.png",
"authors": ["max-ghenis", "nikhil-woodruff"]
"authors": ["max-ghenis", "nikhil-woodruff", "ben-ogorek", "maria-juaristi"]
},
{
"title": "The One Big Beautiful Bill Act, household by household",
"description": "Our latest interactive shows how the reconciliation bill affects each of 20,000 representative households across income levels, states, and provisions.",
"date": "2025-08-11",
"tags": ["us", "policy", "featured", "reconciliation", "interactives"],
"external_url": "/us/obbba-household-by-household",
"image": "obbba-household-by-household.png",
"authors": [
"max-ghenis",
"pavel-makarchuk",
"ben-ogorek",
"nikhil-woodruff"
]
},
{
"title": "Analysis of individual income tax provisions in the final reconciliation bill",
Expand Down
Loading