feat(publication): share policy for manifest routes, canonicals, indexing and sitemap
This commit is contained in:
40 files changed
+846
-282
No files matched your search
@@ -3,7 +3,10 @@ import Button from './Button.astro';
|
||||
import LanguageSwitcher from './LanguageSwitcher.astro';
|
||||
import MainNav from './MainNav.astro';
|
||||
import MobileNav from './MobileNav.astro';
|
||||
import { getPublicationManifest } from '../utils/publication';
|
||||
const { lang = 'en' } = Astro.props;
|
||||
const localizedHome = lang === 'en' ? '/' : `/${lang}`;
|
||||
const homeHref = (await getPublicationManifest()).some((page) => page.eligible && page.route === localizedHome) ? localizedHome : '/';
|
||||
const utility = lang === 'es'
|
||||
? { credit: 'Solicitar CareCredit', bill: 'Pagar mi factura' }
|
||||
: { credit: 'Apply Care Credit', bill: 'Pay My Bill' };
|
||||
@@ -16,7 +19,7 @@ const utility = lang === 'es'
|
||||
</div>
|
||||
</div>
|
||||
<div class="container header-inner">
|
||||
<a class="brand" href={lang === 'en' ? '/' : `/${lang}`}>
|
||||
<a class="brand" href={homeHref}>
|
||||
<img src="/assets/images/aia-logo.svg" alt="Arizona Institute for Autism" width="150" height="70" />
|
||||
</a>
|
||||
<MainNav lang={lang} />
|
||||
|
||||
@@ -1,23 +1,8 @@
|
||||
---
|
||||
import { getCollection } from 'astro:content';
|
||||
import { getPublicationManifest } from '../utils/publication';
|
||||
const pathname = Astro.url.pathname.replace(/\/$/, '') || '/';
|
||||
const bare = pathname.replace(/^\/(ar|es)(?=\/|$)/, '') || '/';
|
||||
const pages = await getCollection('pages', ({ data }) => !data.draft);
|
||||
const posts = await getCollection('blog', ({ data }) => !data.draft);
|
||||
const available = new Set<string>(['/', '/library', '/es', '/es/library', '/ar', '/ar/library']);
|
||||
for (const entry of pages) {
|
||||
const prefix = entry.data.lang === 'en' ? '' : `/${entry.data.lang}`;
|
||||
const route = entry.data.slug === 'index'
|
||||
? prefix || '/'
|
||||
: entry.data.slug === 'library'
|
||||
? `${prefix}/library`
|
||||
: `${prefix}/${entry.data.slug}`;
|
||||
available.add(route);
|
||||
}
|
||||
for (const entry of posts) {
|
||||
const prefix = entry.data.lang === 'en' ? '' : `/${entry.data.lang}`;
|
||||
available.add(`${prefix}/library/${entry.data.slug}`);
|
||||
}
|
||||
const available = new Set((await getPublicationManifest()).filter((page) => page.eligible).map((page) => page.route));
|
||||
|
||||
const langMeta: Record<string, { short: string; full: string }> = {
|
||||
en: { short: 'EN', full: 'English' },
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
---
|
||||
import { allowIndexing } from '../utils/publication';
|
||||
import { robotsFor, type Publication } from '../utils/publication-policy';
|
||||
interface Props {
|
||||
title: string;
|
||||
description?: string;
|
||||
canonical?: string;
|
||||
publication: Publication;
|
||||
image?: string;
|
||||
lang?: string;
|
||||
type?: 'website' | 'article';
|
||||
robots?: string;
|
||||
}
|
||||
const {
|
||||
title,
|
||||
description = '',
|
||||
canonical,
|
||||
publication,
|
||||
image,
|
||||
lang = 'en',
|
||||
type = 'website',
|
||||
robots
|
||||
type = 'website'
|
||||
} = Astro.props;
|
||||
const defaultRobots = import.meta.env.PUBLIC_ALLOW_INDEXING === 'true' ? 'index,follow' : 'noindex,nofollow';
|
||||
const { canonical } = publication;
|
||||
const absoluteImage = image ? new URL(image, Astro.site ?? Astro.url).href : undefined;
|
||||
---
|
||||
<title>{title}</title>
|
||||
<meta name="description" content={description} />
|
||||
<meta name="robots" content={robots ?? defaultRobots} />
|
||||
{canonical && <link rel="canonical" href={canonical} />}
|
||||
<meta name="robots" content={robotsFor(publication, allowIndexing)} />
|
||||
<link rel="canonical" href={canonical} />
|
||||
<meta property="og:type" content={type} />
|
||||
<meta property="og:title" content={title} />
|
||||
<meta property="og:description" content={description} />
|
||||
{canonical && <meta property="og:url" content={canonical} />}
|
||||
<meta property="og:url" content={canonical} />
|
||||
{absoluteImage && <meta property="og:image" content={absoluteImage} />}
|
||||
<meta name="twitter:card" content={absoluteImage ? 'summary_large_image' : 'summary'} />
|
||||
<meta name="twitter:title" content={title} />
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
import { getPublicationManifest } from '../../utils/publication';
|
||||
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||
import HomeHero from '../home/HomeHero.astro';
|
||||
import BlogCard from '../BlogCard.astro';
|
||||
const posts = (await getPublicationManifest()).flatMap(({ eligible, entry }) => eligible && entry.collection === 'blog' && entry.data.lang === 'ar' ? [entry] : []).slice(0, 3);
|
||||
---
|
||||
<BaseLayout title="معهد أريزونا للتوحد" description="موارد ودعم للأسر والأطفال المصابين بالتوحد." lang="ar">
|
||||
<HomeHero section={{ type: 'hero', eyebrow: 'Arizona Institute for Autism', heading: 'الصحة السلوكية والتعليم الخاص', body: 'محتوى عربي متاح من مكتبة معهد أريزونا للتوحد.', cta: { label: 'ابدأ الآن', href: '/ar' }, image: 'playing-boy.webp', imageAlt: '' }} />
|
||||
<section class="section"><div class="container"><div class="section-heading"><h2>المكتبة</h2></div><div class="card-grid">{posts.map((post) => <BlogCard post={post} prefix="/ar" />)}</div></div></section>
|
||||
</BaseLayout>
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
import { getEntry } from 'astro:content';
|
||||
import type { CollectionEntry } from 'astro:content';
|
||||
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||
import HomeBenefits from '../home/HomeBenefits.astro';
|
||||
import HomeDirector from '../home/HomeDirector.astro';
|
||||
@@ -13,12 +13,9 @@ import HomeSkills from '../home/HomeSkills.astro';
|
||||
import HomeTestimonials from '../home/HomeTestimonials.astro';
|
||||
import type { HomePageContent, HomeSection } from '../../types/home-sections';
|
||||
|
||||
interface Props { lang?: string }
|
||||
const { lang = 'en' } = Astro.props;
|
||||
const es = lang === 'es';
|
||||
const entry = await getEntry('pages', es ? 'es/index' : 'en/index');
|
||||
if (!entry) throw new Error(`[HomePage] Content entry not found for lang="${lang}". If running in dev, restart the dev server to rebuild the content layer cache.`);
|
||||
const { title, description, canonical } = entry.data;
|
||||
interface Props { entry: CollectionEntry<'pages'> }
|
||||
const { entry } = Astro.props;
|
||||
const { title, description, lang } = entry.data;
|
||||
|
||||
function fromHomeContent(home: HomePageContent): HomeSection[] {
|
||||
return [
|
||||
@@ -39,7 +36,7 @@ const sections: HomeSection[] = entry.data.home
|
||||
? fromHomeContent(entry.data.home)
|
||||
: ((entry.data.sections ?? []) as HomeSection[]);
|
||||
---
|
||||
<BaseLayout {title} {description} {canonical} {lang}>
|
||||
<BaseLayout {title} {description} {lang}>
|
||||
{sections.map((section) => {
|
||||
switch (section.type) {
|
||||
case 'hero':
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
import { getPublicationManifest } from '../../utils/publication';
|
||||
import BlogIndexLayout from '../../layouts/BlogIndexLayout.astro';
|
||||
import BlogCard from '../BlogCard.astro';
|
||||
const posts = (await getPublicationManifest()).flatMap(({ eligible, entry }) => eligible && entry.collection === 'blog' && entry.data.lang === 'ar' ? [entry] : []).sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
|
||||
const popular = posts.slice(0, 5);
|
||||
---
|
||||
<BlogIndexLayout title="مكتبة معهد أريزونا للتوحد" description="مقالات إخبارية حول علاج تحليل السلوك التطبيقي والتعليم الخاص، ودراسات حالة، ووصفات، ومقالات افتتاحية، ودروس تعليمية." lang="ar">
|
||||
<div class="blog-list">{posts.map((post) => <BlogCard post={post} prefix="/ar" />)}</div>
|
||||
<aside class="library-sidebar"><h2>المقالات الشائعة</h2><ul>{popular.map((post) => <li><a href={`/ar/library/${post.data.slug}`}>{post.data.title}</a></li>)}</ul></aside>
|
||||
</BlogIndexLayout>
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
import { getPublicationManifest } from '../../utils/publication';
|
||||
import BlogIndexLayout from '../../layouts/BlogIndexLayout.astro';
|
||||
import BlogCard from '../BlogCard.astro';
|
||||
const posts = (await getPublicationManifest()).flatMap(({ eligible, entry }) => eligible && entry.collection === 'blog' && entry.data.lang === 'en' ? [entry] : []).sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
|
||||
const popular = posts.slice(0, 5);
|
||||
---
|
||||
<BlogIndexLayout
|
||||
title="The Library at AZ Institute for Autism"
|
||||
description="Welcome to the Library at AIA, where we share valuable insights, strategies, and resources to support individuals with autism, their families, and professionals in the field. Our articles explore key topics in Applied Behavior Analysis (ABA) therapy, community events, success stories, and expert guidance."
|
||||
intro={[
|
||||
"Welcome to the Library at AIA, where we share valuable insights, strategies, and resources to support individuals with autism, their families, and professionals in the field. Our articles explore key topics in Applied Behavior Analysis (ABA) therapy, including teaching self-advocacy, proactive and reactive strategies, and innovative intervention techniques.",
|
||||
"We also highlight community events, success stories, and expert guidance to foster understanding and empowerment. Whether you're a parent, caregiver, educator, or advocate, our goal is to provide meaningful content that helps children with autism reach their highest potential in a compassionate and supportive environment. Stay connected with us as we continue to share knowledge and celebrate progress!",
|
||||
]}
|
||||
>
|
||||
<div class="blog-list">{posts.map((post) => <BlogCard post={post} />)}</div>
|
||||
<aside class="library-sidebar">
|
||||
<label for="library-search">Search</label>
|
||||
<input id="library-search" type="search" placeholder="Search" />
|
||||
<h2>Popular Posts</h2>
|
||||
<ul>{popular.map((post) => <li><a href={`/library/${post.data.slug}`}>{post.data.title}</a></li>)}</ul>
|
||||
</aside>
|
||||
</BlogIndexLayout>
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
import { getPublicationManifest } from '../../utils/publication';
|
||||
import BlogIndexLayout from '../../layouts/BlogIndexLayout.astro';
|
||||
import BlogCard from '../BlogCard.astro';
|
||||
const posts = (await getPublicationManifest()).flatMap(({ eligible, entry }) => eligible && entry.collection === 'blog' && entry.data.lang === 'es' ? [entry] : []).sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
|
||||
const popular = posts.slice(0, 5);
|
||||
---
|
||||
<BlogIndexLayout title="La Biblioteca en AZ Institute for Autism" description="Noticias sobre terapia ABA y educación especial, casos de estudio, recetas, editoriales y tutoriales para y sobre nuestros estudiantes con autismo." lang="es">
|
||||
<div class="blog-list">{posts.map((post) => <BlogCard post={post} prefix="/es" />)}</div>
|
||||
<aside class="library-sidebar"><h2>Publicaciones populares</h2><ul>{popular.map((post) => <li><a href={`/es/library/${post.data.slug}`}>{post.data.title}</a></li>)}</ul></aside>
|
||||
</BlogIndexLayout>
|
||||
Reference in new issue
Block a user