Skip to content

Commit 017a1de

Browse files
jdchoi77cursoragent
andcommitted
Serve the latest Dispatch issue directly at /dispatch/.
Extract shared issue rendering into DispatchIssueView so /dispatch/ loads the current issue without a redirect hop. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent ca6c0c5 commit 017a1de

4 files changed

Lines changed: 77 additions & 52 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Content is Markdown with YAML frontmatter, typed via [`src/content.config.ts`](s
3030
| People | [`src/content/people/`](src/content/people/) | `current: true` keeps someone in the **Current** list. |
3131
| Papers | [`src/content/papers/`](src/content/papers/) | Authors, venue, year, optional links. Optional `topics` object (`researchField?`, `applicationDomain`, `task`) on Dispatch lists. Served at `/papers/`. |
3232
| Theses & diss. | [`src/content/theses/`](src/content/theses/) | `degree` and defense `date` are required in the schema. Optional `topics` for Dispatch (inferred from title/abstract when omitted). |
33-
| The NLP Dispatch | [`src/content/dispatch/`](src/content/dispatch/) | Triannual magazine issues (`/dispatch/` redirects to the latest issue; `/dispatch/issues/{slug}/` for each issue). Curates publication and thesis slugs plus editorial fields (column, spotlight, reading list, `distinctions`, activity news). Optional `featured: true` on one item per section (`papers`, `activityNews`, `distinctions`, `theses`) spotlights it at the top of that section. |
33+
| The NLP Dispatch | [`src/content/dispatch/`](src/content/dispatch/) | Triannual magazine issues (`/dispatch/` serves the latest issue; `/dispatch/issues/{slug}/` for permalinks). Curates publication and thesis slugs plus editorial fields (column, spotlight, reading list, `distinctions`, activity news). Optional `featured: true` on one item per section (`papers`, `activityNews`, `distinctions`, `theses`) spotlights it at the top of that section. |
3434
| Seminars | [`src/content/seminars/`](src/content/seminars/) | `term` drives grouping on the seminars index page. |
3535
| News | [`src/content/news/`](src/content/news/) | `featured: true` prioritizes the home carousel; optional `coverImage: /news/your.webp` (images under [`public/news/`](public/news/)). |
3636

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
---
2+
import type { CollectionEntry } from 'astro:content';
3+
import { render } from 'astro:content';
4+
import DispatchLayout from '../../layouts/DispatchLayout.astro';
5+
import DispatchEditionHeader from './DispatchEditionHeader.astro';
6+
import {
7+
buildDispatchEditionTickerItems,
8+
dispatchIssueTagline,
9+
formatDispatchVolumeIssueLine,
10+
} from '../../lib/dispatch/editionTicker';
11+
import DispatchPaperList from './DispatchPaperList.astro';
12+
import DispatchColumn from './DispatchColumn.astro';
13+
import DispatchStudentSpotlight from './DispatchStudentSpotlight.astro';
14+
import DispatchActivityBento from './DispatchActivityBento.astro';
15+
import DispatchDistinctions from './DispatchDistinctions.astro';
16+
import DispatchReadingList from './DispatchReadingList.astro';
17+
import DispatchThesesShowcase from './DispatchThesesShowcase.astro';
18+
import { loadDispatchCatalog, resolveDispatchIssue } from '../../lib/dispatch/resolveIssue';
19+
20+
interface Props {
21+
entry: CollectionEntry<'dispatch'>;
22+
}
23+
24+
const { entry } = Astro.props;
25+
26+
const catalog = await loadDispatchCatalog();
27+
const resolved = resolveDispatchIssue(entry, catalog);
28+
const d = entry.data;
29+
30+
const issueTagline = dispatchIssueTagline(resolved);
31+
const tickerItems = buildDispatchEditionTickerItems(resolved);
32+
const columnArticles = await Promise.all(
33+
resolved.columns.map(async (column) => {
34+
if (column.format === 'external') return column;
35+
return { ...column, ...(await render(column.entry)) };
36+
}),
37+
);
38+
const volumeLine = formatDispatchVolumeIssueLine(d.volume, d.issue);
39+
---
40+
41+
<DispatchLayout title={volumeLine} description={d.issueTitle}>
42+
<article class="dispatch-issue">
43+
<DispatchEditionHeader
44+
variant="issue"
45+
title={d.issueTitle}
46+
tagline={issueTagline}
47+
tickerItems={tickerItems}
48+
tickerAriaLabel={`${volumeLine} summary`}
49+
/>
50+
<DispatchDistinctions items={resolved.distinctions} featured={resolved.featuredDistinction} />
51+
<DispatchPaperList papers={resolved.papers} featured={resolved.featuredPaper} />
52+
<DispatchThesesShowcase theses={resolved.theses} featured={resolved.featuredThesis} />
53+
<DispatchColumn articles={columnArticles} />
54+
{d.studentSpotlight ? (
55+
<DispatchStudentSpotlight spotlight={d.studentSpotlight} />
56+
) : null}
57+
<DispatchActivityBento items={resolved.activityNews} />
58+
<DispatchReadingList items={resolved.readingList} />
59+
</article>
60+
</DispatchLayout>

src/pages/dispatch/index.astro

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
---
22
import { getCollection } from 'astro:content';
3+
import DispatchIssueView from '../../components/dispatch/DispatchIssueView.astro';
4+
import DispatchLayout from '../../layouts/DispatchLayout.astro';
35
import { pickCurrentDispatchIssue } from '../../lib/dispatch/issueSort';
4-
import { siteHref } from '../../lib/siteHref';
56
67
const issues = await getCollection('dispatch');
78
const current = pickCurrentDispatchIssue(issues);
9+
---
810

9-
if (current) {
10-
return Astro.redirect(siteHref(`/dispatch/issues/${current.id}/`));
11+
{
12+
current ? (
13+
<DispatchIssueView entry={current} />
14+
) : (
15+
<DispatchLayout title="Emory NLP Dispatch" description="Emory NLP Dispatch — research magazine from Emory NLP.">
16+
<div class="dispatch-wrap" style="padding: 3rem 0;">
17+
<div class="empty-state surface">No Dispatch issues published yet.</div>
18+
</div>
19+
</DispatchLayout>
20+
)
1121
}
12-
13-
return Astro.redirect(siteHref('/'));
14-
---
Lines changed: 3 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,9 @@
11
---
22
import type { CollectionEntry } from 'astro:content';
3-
import DispatchLayout from '../../../layouts/DispatchLayout.astro';
4-
import DispatchEditionHeader from '../../../components/dispatch/DispatchEditionHeader.astro';
5-
import { buildDispatchEditionTickerItems, dispatchIssueTagline, formatDispatchVolumeIssueLine } from '../../../lib/dispatch/editionTicker';
6-
import DispatchPaperList from '../../../components/dispatch/DispatchPaperList.astro';
7-
import DispatchColumn from '../../../components/dispatch/DispatchColumn.astro';
8-
import DispatchStudentSpotlight from '../../../components/dispatch/DispatchStudentSpotlight.astro';
9-
import DispatchActivityBento from '../../../components/dispatch/DispatchActivityBento.astro';
10-
import DispatchDistinctions from '../../../components/dispatch/DispatchDistinctions.astro';
11-
import DispatchReadingList from '../../../components/dispatch/DispatchReadingList.astro';
12-
import DispatchThesesShowcase from '../../../components/dispatch/DispatchThesesShowcase.astro';
3+
import DispatchIssueView from '../../../components/dispatch/DispatchIssueView.astro';
134
import { listDispatchIssueSlugs } from '../../../lib/dispatch/issueSlugs';
14-
import { loadDispatchCatalog, resolveDispatchIssue } from '../../../lib/dispatch/resolveIssue';
155
import { siteHref } from '../../../lib/siteHref';
16-
import { getEntry, render } from 'astro:content';
6+
import { getEntry } from 'astro:content';
177
188
export async function getStaticPaths() {
199
const slugs = await listDispatchIssueSlugs();
@@ -29,38 +19,6 @@ const entry =
2919
if (entry === undefined) {
3020
return Astro.redirect(siteHref('/dispatch/'));
3121
}
32-
33-
const catalog = await loadDispatchCatalog();
34-
const resolved = resolveDispatchIssue(entry, catalog);
35-
const d = entry.data;
36-
37-
const issueTagline = dispatchIssueTagline(resolved);
38-
const tickerItems = buildDispatchEditionTickerItems(resolved);
39-
const columnArticles = await Promise.all(
40-
resolved.columns.map(async (column) => {
41-
if (column.format === 'external') return column;
42-
return { ...column, ...(await render(column.entry)) };
43-
}),
44-
);
4522
---
4623

47-
<DispatchLayout title={formatDispatchVolumeIssueLine(d.volume, d.issue)} description={d.issueTitle}>
48-
<article class="dispatch-issue">
49-
<DispatchEditionHeader
50-
variant="issue"
51-
title={d.issueTitle}
52-
tagline={issueTagline}
53-
tickerItems={tickerItems}
54-
tickerAriaLabel={`${formatDispatchVolumeIssueLine(d.volume, d.issue)} summary`}
55-
/>
56-
<DispatchDistinctions items={resolved.distinctions} featured={resolved.featuredDistinction} />
57-
<DispatchPaperList papers={resolved.papers} featured={resolved.featuredPaper} />
58-
<DispatchThesesShowcase theses={resolved.theses} featured={resolved.featuredThesis} />
59-
<DispatchColumn articles={columnArticles} />
60-
{d.studentSpotlight ? (
61-
<DispatchStudentSpotlight spotlight={d.studentSpotlight} />
62-
) : null}
63-
<DispatchActivityBento items={resolved.activityNews} />
64-
<DispatchReadingList items={resolved.readingList} />
65-
</article>
66-
</DispatchLayout>
24+
<DispatchIssueView entry={entry} />

0 commit comments

Comments
 (0)