getPagesUnderRoute
This function is imported from file nextra/context.js (opens in a new tab)
import { getPagesUnderRoute } from 'nextra/context'
When called with a string as argument, it returns an array of Page
objects that are under the route passed as argument. Here it is the source code:
export function getPagesUnderRoute(route: string): Page[] {
const { pageMap } = getContext('getPagesUnderRoute')
return filter(pageMap, route).activeLevelPages
}
it returns an array of Page
objects that are under the route passed as argument. The Page
type is defined as follows:
export type Page = (MdxFile | Folder<Page>) & {
meta?: Exclude<Meta, string>
}
What seems to be interesting is the frontMatter
property of the MdxFile
type.
export type FrontMatter = GrayMatterFile<string>['data']
export type Meta = string | Record<string, any>
export type MdxFile<FrontMatterType = FrontMatter> = {
kind: 'MdxPage'
name: string
route: string
locale?: string
frontMatter?: FrontMatterType
}
This way we can access the frontMatter
of the MdxFile
object and use it to filter the pages we want to display. Here is an example of such a page:
{
kind: 'MdxPage',
name: '2024-01-23-leccion',
route: '/clases/january/2024-01-23-leccion',
frontMatter: {
title: 'Tuesday 2024/01/23',
published: true,
summary: 'Encuesta. Primeras prácticas. Un vistazo a las primeras etapas de un compilador: análisis léxico',
labs: [Array],
topics: [Array],
videos: [Array]
},
meta: { title: 'Tuesday 2024/01/23' }
}
- Other properties are
name
androute
that can be used to build links to the pages. - The attribute
kind
is a string that can have the value'MdxPage'
or'Folder'
and it is used to distinguish between pages and folders.
Here is an example of Folder
object:
{
kind: 'Folder',
name: 'tree-transformations',
route: '/topics/tree-transformations',
children: [ [Object], ... [Object] ],
meta: { title: 'Tree Transformations' }
},
The children
of a Folder
is an array of FileType
objects:
export interface Folder<FileType = PageMapItem> {
kind: 'Folder'
name: string
route: string
children: FileType[]
}
export type PageMapItem = Folder | MdxFile | MetaJsonFile
The following is the code of a version of the CollectionPage (opens in a new tab) component in this notes:
import Link from 'next/link'
import { useRouter } from 'next/router'
import { getPagesUnderRoute } from 'nextra/context'
import filterRouteLocale from 'nextra/filter-route-locale'
import styles from './counters.module.css'
import LabInfo from '@/components/LabInfo'
import ClassInfo from '@/components/ClassInfo'
export function CollectionPage({ path }) {
const { locale, defaultLocale } = useRouter()
const pages = getPagesUnderRoute(path)
let result = filterRouteLocale(pages, locale, defaultLocale).map(page => {
if (page.frontMatter?.display === 'hidden') return null
return (
<li key={page.route}>
<Link className={styles.link} href={page.route}>{page.meta?.title || page.frontMatter?.title || page?.name}</Link>
{path === '/labs' && <LabInfo page={page} />}
{path.startsWith('/clases') && <ClassInfo page={page} />}
</li>
)
})
return (<ol className={styles.myList} reversed>{result}</ol>)
}
- Here is the code of the LabInfo (opens in a new tab) component used in the former example.
- Here is the code of the ClassInfo (opens in a new tab) component used in the former example.
Example
The following code is an example of how to use the getPagesUnderRoute
function to build a list of links to the pages under the route /labs
:
import GetSpecific from '@/components/getSpecific'
<GetSpecific path="/labs"/>
The following is the code of the getSpecific
component:
import Link from 'next/link'
import { getPagesUnderRoute } from 'nextra/context'
import filterRouteLocale from 'nextra/filter-route-locale'
import { useRouter } from 'next/router'
import styles from './counters.module.css'
import React from 'react'
export default function getSpecific({ path }) {
const { locale, defaultLocale } = useRouter()
const pages = getPagesUnderRoute(path)
console.error(pages)
let result = filterRouteLocale(pages, locale, defaultLocale).map(page => {
if (page.frontMatter?.display === 'hidden') return null
return (
<li key={page.route}>
<Link className={styles.link} href={page.route}>{page.meta?.title || page.frontMatter?.title || page?.name}</Link> {page.frontMatter?.key}
</li>
)
})
return (<ol className={styles.myList} reversed>{result}</ol>)
}
Here is the output of the former code:
- Training Exam training-exam
- TFA: Final Project tfa
- Translating Egg to JS egg-2-js
- Extended Egg Interpreter extended-egg
- Egg OOP Parser egg-oop-parser
- Egg Interpreter egg-interpreter
- Pattern Matching pattern-matching
- Calculator. Funs on the left side. Multiple arguments left-side
- Lexer Generator lexer-generator
- Adding Loops to the Calculator while
- Egg Parser egg-parser
- Functions functions
- Scope Intro scope-intro
- Hello Compiler hello-compilers
- Translating Arithmetic Expressions to JavaScript arith2js
- IAAS iaas
- Visual Studio Code and Gitpod visual-studio-code
- GitHub Project Board github-project-board
- GitHub Campus Expert github-campus-expert
- Fill the form
If I substitute line 12 by console.error(pages[0])
I've got the following object as the first page of /labs
:
{
kind: 'MdxPage',
name: 'functions',
route: '/labs/functions',
frontMatter: {
title: 'Adding Functions to the Calculator',
key: 'functions',
published: true,
date: '2023/03/21',
delivery: '2023/03/30',
campus: 'https://campusingenieriaytecnologia2223.ull.es/mod/assign/view.php?id=28190&forceview=1',
order: 12,
layout: 'Practica',
sidebar: 'auto',
prev: 'constant-folding.md',
next: null,
rubrica: [
'El paquete está publicado en GitHub Registry',
'Se comprueba que el módulo npm se instala desde el GitHub Registry y funciona',
'Probar que el ejecutable queda correctamente instalado, puede ser ejecutado con el nombre publicado y produce salidas correctas',
'Opciones en línea de comandos (-o, -V, -h, etc.)',
'Traduce correctamente las funciones',
'Traduce correctamente las llamadas encadenadas',
'Traduce correctamente las expresiones lógicas',
'Se declaran las variables inicializadas en el preámbulo de las funciones o del programa',
'Da mensajes de error para variables no declaradas',
'Los mensajes de error ayudan a la detección de errores',
'Ha añadido tests suficientes, documentación y cubrimiento',
'Se publica la documentación usando un static generator, API docs y Covering',
'Se ha añadido el enlace a las GH pages en el "About" del repo'
],
video20230308: {
date: '08/03/2023',
description: 'Clase del 08/03/2023. Se describe el soporte para scopes de ast-types',
id: 'CR_GI81TFt0'
},
video20230313: {
date: '13/03/2023',
description: 'Clase del 13/03/2023. Se describe el soporte de ast-types para el recorrrido y modificación de nodos (Métodos visit)',
url: 'https://youtu.be/CR_GI81TFt0',
id: 'CR_GI81TFt0'
},
video20230322: {
date: '22/03/2023',
description: 'Clase del 22/03/2023. Hasta el minuto 25 se explica como realizar el examen parcial del curso 22/23. Le será muy útil para preparar examenes. A partir del minuto 25 se explican las bases para la práctica functions',
url: 'https://youtu.be/SfAIHgAqSuQ',
id: 'SfAIHgAqSuQ'
},
video20230327: {
date: '27/03/2023',
description: 'Clase del 27/03/2023. Se continúa la explicación de como realizar la práctica de funciones',
url: 'https://youtu.be/DRP-_bmTdto',
id: 'DRP-_bmTdto'
},
video20230328: {
date: '28/03/2023',
description: 'Clase del 28/03/2023. Análisis de tipos en el lab. Lookup en el scope analysis. Soporte a las operaciones para los nuevos tipos. Nueva sintáxis para las calls',
url: 'https://youtu.be/XpzNZJ-fwx8',
id: 'XpzNZJ-fwx8'
}
},
meta: {
type: 'menu',
title: 'Functions',
display: 'normal',
items: {
'Añadiendo funciones a la calculadora': [Object],
'Las funciones son expresiones': [Object],
'Funciones que retornan funciones': [Object],
'Funciones que reciben funciones y retornan funciones': [Object],
'Encadenamiento de llamadas': [Object],
Comentarios: [Object],
'Operadores Lógicos y de Comparación': [Object],
'Short Circuit Evaluation and if then else': [Object],
'Type Handling in Dynamic Languages': [Object],
'Type Checking: Basic concepts': [Object],
'Function Arithmetic': [Object],
'Arithmetic of Functions ad numbers': [Object],
'Arithmetic of Functions and Booleans': [Object],
'New Semantic needs New Syntax': [Object],
'Type Promotion': [Object],
'Language Symmetry': [Object],
'Be bold in your designs but keep them simple.': [Object],
Videos: [Object],
'Vídeos sobre manejo del AST con ast-types': [Object],
'Smells, The Open Closed Principle, the Switch Smell and the Strategy pattern': [Object],
'Pruebas, Covering e Integración Continua': [Object],
'Avoiding the preamble in the tests': [Object],
'Documentación': [Object],
References: [Object]
}
}
}
Notice the meta
attribute of the MdxPage
object that seems to correspond to the information inside the _meta.json
file about
page[0]
(lab functions
).
Getting a lab by key
import GetLabByKey from '@/components/getLabByKey'
<GetLabByKey labKey="functions"/>
➜ pl2324-apuntes git:(main) cat components/getLabByKey.jsx
import { getPagesUnderRoute } from 'nextra/context'
import filterRouteLocale from 'nextra/filter-route-locale'
import { useRouter } from 'next/router'
// returns the page for a given labKey
export default function getLabByKey({ labKey }) {
const pages = getPagesUnderRoute("/labs")
console.error("labKey=", labKey)
//console.error(pages[0])
let result = pages.filter(page => {
return (page?.frontMatter?.key === labKey)
})
//console.error("Result\n", result)
return (<div>{result[0].frontMatter.title}</div>)
}