diff --git a/src/content/docs/es/plugins/extended.mdx b/src/content/docs/es/plugins/extended.mdx new file mode 100644 index 00000000..9785f464 --- /dev/null +++ b/src/content/docs/es/plugins/extended.mdx @@ -0,0 +1,317 @@ +--- +i18nReady: true +title: Haciendo complementos útiles +description: Aprende sobre los complementos de StudioCMS y cómo funcionan. +sidebar: + order: 2 +--- + +import ReadMore from '~/components/ReadMore.astro' +import { FileTree } from '@astrojs/starlight/components' + +# Introducción + +Crear un complemento para StudioCMS es una forma poderosa de extender la funcionalidad de StudioCMS. Los complementos proporcionan una manera simple y flexible de agregar nuevas características a tu proyecto StudioCMS. A continuación se muestra un ejemplo básico de cómo crear un complemento de StudioCMS y cómo funciona. + +## Primeros Pasos + +Para comenzar, necesitarás crear un nuevo complemento de StudioCMS. A continuación se muestra un ejemplo básico de la estructura de archivos para un complemento de StudioCMS: + + + +- package.json +- src + - index.ts + - routes + - [...slug].astro + - dashboard-grid-items + - MyPluginGridItem.astro + + + +## Creando el complemento + +En el archivo principal `src/index.ts`, definirás el complemento de StudioCMS. A continuación se muestra un ejemplo de cómo definir un complemento de StudioCMS que incluye una Integración Astro para crear un ejemplo simple de blog: + +```ts twoslash title="index.ts" +import { definePlugin } from 'studiocms/plugins'; +import { AstroIntegration } from 'astro'; +import { addVirtualImports, createResolver } from 'astro-integration-kit'; + +// Define the options for the complemento and integration +interface Options { + route: string; +} + +export function studioCMSPageInjector(options: Options) { + + // Resuelve la ruta al archivo actual + const { resolve } = createResolver(import.meta.url); + + // Define la Integración Astro + function myIntegration(options: Options): AstroIntegration { + const route = `/${options?.route || 'my-plugin'}`; + + return { + name: 'my-astro-integration', + hooks: { + "astro:config:setup": (params) => { + const { injectRoute } = params; + + // Inyecta la ruta para el complemento + injectRoute({ + entrypoint: resolve('./routes/[...slug].astro'), + pattern: `/${route}/[...slug]`, + prerender: false, + }) + + addVirtualImports(params, { + name: 'my-astro-integration', + imports: { + 'myplugin:config': ` + export const options = ${JSON.stringify({ route })}; + export default options; + `, + } + }) + } + } + } + } + + // Define el complemento de StudioCMS + return definePlugin({ + identifier: 'my-plugin', + name: 'My Plugin', + studiocmsMinimumVersion: '0.1.0-beta.8', + integration: myIntegration(options), // Opcional, pero recomendado + // Define los enlaces de navegación del frontend para el complemento (opcional) + // Esto es útil si estás usando los ayudantes de navegación de StudioCMS incorporados en tu diseño, + // como cuando usas el complemento `@studiocms/blog`. + frontendNavigationLinks: [{ label: 'Title here', href: options?.route || 'my-plugin' }], + // Cuando estes creando pageTypes, también puedes definir un `pageContentComponent` si tu complemento requiere un editor de contenido personalizado. + // pageTypes: [{ identifier: 'my-plugin', label: 'Blog Post (My plugin)', pageContentComponent: resolve('./components/MyContentEditor.astro') }], + // In this example we are okay using the default content editor (markdown). + pageTypes: [{ identifier: 'my-plugin', label: 'Blog Post (My plugin)' }], + // Definir los elementos de la cuadrícula para el panel + // Estos son los elementos que serán mostrados en el panel de StudioCMS + // Puedes definir tantos elementos como desees + // En este ejemplo, estamos definiendo un solo elemento, que tiene un span de 2 y requiere el permiso 'editor' e inyecta un componente Astro que reemplaza el elemento personalizado de html plano. + dashboardGridItems: [ + { + name: 'example', + span: 2, + variant: 'default', + requiresPermission: 'editor', + header: { title: 'Example', icon: 'bolt' }, + body: { + // Siempre usa html plano sin `-` o caracteres especiales en las etiquetas, se reemplazarán con el componente Astro y este HTML nunca se renderizará + html: '', + components: { + // Inyecta el componente de Astro para reemplazar el elemento personalizado en html plano + examplegriditem: resolve('./dashboard-grid-items/MycomplementoGridItem.astro') + } + } + } + ], + }); +} +``` + +El ejemplo anterior define un complemento de StudioCMS que incluye una Integración Astro para crear un ejemplo simple de blog. El complemento incluye una ruta que se inyecta en el proyecto StudioCMS y un elemento de cuadrícula que se muestra en el Panel de Control de StudioCMS. + +Para más información sobre cómo crear una Integración Astro, consulta el [Kit de Integración Astro](https://astro-integration-kit.netlify.app/) y la [documentación de Integraciones de Astro](https://docs.astro.build/es/reference/integrations-reference/). + +## Ejemplo de ruta + +En el archivo `src/routes/[...slug].astro`, definirás la ruta para el complemento. A continuación se muestra un ejemplo de cómo definir una ruta para el complemento, lo dividiremos en dos partes, la primera parte es el frontmatter (entre las marcas `---`), y la segunda parte es la plantilla HTML que se coloca debajo del segundo `---`. + +```ts twoslash title="Frontmatter" +// @noErrors +// @filename: plugin.d.ts +declare module 'myplugin:config' { + export const options: { route: string }; + export default options; +} +// ---cut--- +// @filename: Frontmatter.ts +/// +/// +/// +import type { AstroGlobal } from 'astro'; +const Astro: AstroGlobal = {}; +// ---cut--- +import { StudioCMSRenderer } from 'studiocms:renderer'; +import sdk from 'studiocms:sdk'; +import config from 'myplugin:config'; + +const makeRoute = (slug: string) => { + return `/${config.route}/${slug}`; +} + +// 'my-plugin' aquí se usa como identificador para +// el pageType de la definición del complemento +const pages = await sdk.GET.packagePages('my-complemento'); + +const { slug } = Astro.params; + +const page = pages.find((page) => page.slug === slug || ''); +``` + +```astro title="Template" +{ + slug && page ? ( +
+

{page.title}

+ +
+ ) : ( +
+

Mi complemento

+
    + {pages.length > 0 && pages.map((page) => ( +
  • + {page.title} +
  • + ))} +
+
+ ) +} +``` + +El ejemplo anterior define una [ruta dinámica](https://docs.astro.build/es/guides/routing/#rutas-dinámicas) para el complemento que muestra una lista de entradas de blog cuando no se proporciona un slug y muestra el contenido de una entrada de blog cuando se proporciona un slug. + +## Ejemplo de elemento de cuadrícula + +En el archivo `src/dashboard-grid-items/MyPluginGridItem.astro`, definirás el elemento de cuadrícula para el complemento. A continuación se muestra un ejemplo de cómo definir un elemento de cuadrícula para el complemento: + +```astro title="MyPluginGridItem.astro" +--- +import { StudioCMSRoutes } from 'studiocms:lib'; +import sdk from 'studiocms:sdk'; + +// 'my-plugin' aqui es usado como el identificador para +// el pageType de la definición del complemento +const pages = await sdk.GET.packagePages('my-complemento'); + +// Consigue las últimas 5 páginas actualizadas en los últimos 30 días +const recentlyUpdatedPages = pages + .filter((page) => { + const now = new Date(); + const thirtyDaysAgo = new Date(now.setDate(now.getDate() - 30)); + return new Date(page.updatedAt) > thirtyDaysAgo; + }) + .sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()) + .slice(0, 5); +--- + +
+

Páginas Actualizadas Recientemente

+
    + {recentlyUpdatedPages.length > 0 && recentlyUpdatedPages.map((page) => ( +
  • + {page.title} +
  • + ))} +
+
+``` + +El ejemplo anterior define un elemento de cuadrícula para el complemento que muestra las 5 páginas actualizadas más recientemente de los últimos 30 días. El elemento de cuadrícula incluye una lista de enlaces a la página de edición de gestión de contenido para cada página. + +## Integrando con los ayudantes de FrontendNavigationLinks + +Si deseas usar los ayudantes de navegación incorporados de StudioCMS en tu proyecto, similar a como lo hace el complemento `@studiocms/blog`, puedes crear un componente personalizado `Navigation.astro`: + +```astro title="Navigation.astro" +--- +import { StudioCMSRoutes } from 'studiocms:lib'; +import studioCMS_SDK from 'studiocms:sdk/cache'; +import { frontendNavigation } from 'studiocms:complemento-helpers'; + +// Define las props para el componente de navegación +interface Props { + topLevelLinkCount?: number; +}; + +// Consigue el enlace de nivel superior de las props +const { topLevelLinkCount = 3 } = Astro.props; + +// Consigue la configuración del sitio y la lista de páginas +const config = (await studioCMS_SDK.GET.siteConfig()).data; + +// Consigue el título del sitio de la configuración +const { title } = config || { title: 'StudioCMS' }; + +// Consigue la URL principal del sitio +const { + mainLinks: { baseSiteURL }, +} = StudioCMSRoutes; + +// Define las props de enlace para la navegación +type LinkProps = { + text: string; + href: string; +}; + +// Define los enlaces para la navegación +const links: LinkProps[] = await frontendNavigation(); +--- +{/* Si no hay elementos dropdown */} +{ ( links.length < topLevelLinkCount || links.length === topLevelLinkCount ) && ( + +) } + +{/* Si hay elementos dropdown */} +{ links.length > topLevelLinkCount && ( + +) } +``` + +El ejemplo anterior define un componente personalizado `Navigation.astro` que utiliza los ayudantes de navegación incorporados de StudioCMS para crear un menú de navegación para el proyecto. El componente incluye enlaces a la URL principal del sitio, la página de índice y cualquier otra página que esté configurada para mostrarse en la navegación. + +Todo lo que necesitas hacer es agregar algunos estilos, y tendrás un menú de navegación completamente funcional que funciona con los ayudantes de navegación incorporados de StudioCMS. \ No newline at end of file diff --git a/src/content/docs/es/plugins/index.mdx b/src/content/docs/es/plugins/index.mdx new file mode 100644 index 00000000..1b6d01b5 --- /dev/null +++ b/src/content/docs/es/plugins/index.mdx @@ -0,0 +1,242 @@ +--- +i18nReady: true +title: Los Fundamentos +description: Aprende sobre los plugins de StudioCMS y cómo funcionan. +sidebar: + order: 1 +--- + +import ReadMore from '~/components/ReadMore.astro' + +# Introducción + +Los plugins de StudioCMS son una herramienta poderosa que te permite extender la funcionalidad de StudioCMS. Proporcionan una manera simple y flexible de añadir nuevas características a tu proyecto StudioCMS. A continuación se muestra un desglose de los plugins de StudioCMS y cómo funcionan. + +## ¿Qué son los complementos? + +Los plugins de StudioCMS son similares a las Integraciones de Astro, pero tienen información adicional adjunta al objeto de función. Esta información es utilizada por StudioCMS para determinar cómo debe cargarse y utilizarse el complemento. Los plugins de StudioCMS se utilizan para extender la funcionalidad de StudioCMS añadiendo nuevas características o modificando las existentes. + +### El tipo de complemento StudioCMS + +```ts twoslash +import { APIRoute, AstroIntegration } from "astro" +import type { HeroIconName } from '@studiocms/ui/components/Icon/iconType.js'; +import type { SanitizeOptions } from 'ultrahtml/transformers/sanitize'; +import type { SettingsField } from 'studiocms/schemas'; +// ---cut--- +type StudioCMSPlugin = { + /** + * Identificador del complemento desde el package.json + */ + identifier: string; + + /** + * Etiqueta del complemento para mostrar en el Panel de Control de StudioCMS + */ + name: string; + + /** + * Versión mínima de StudioCMS requerida para que el complemento funcione + */ + studiocmsMinimumVersion: string; + + /** + * Integración(es) de Astro que proporciona el complemento + */ + integration?: AstroIntegration | AstroIntegration[] | undefined; + + /** + * Si es verdadero, el complemento habilitará la generación del mapa del sitio + */ + triggerSitemap?: boolean; + + /** + * Permite que el complemento añada puntos finales del mapa del sitio + */ + sitemaps?: Array<{ + + /** + * Nombre del complemento + */ + pluginName: string; + + /** + * Ruta al archivo de punto final XML del mapa del sitio + */ + sitemapXMLEndpointPath: string | URL; + }> | undefined; + + /** + * Permite que el complemento añada elementos personalizados a la cuadrícula del panel + */ + dashboardGridItems?: Array<{ + + /** + * Nombre del elemento de cuadrícula + */ + name: string; + + /** + * Extensión del elemento de cuadrícula + */ + span: 1 | 2 | 3; + + /** + * Variante de tarjeta del elemento de cuadrícula + */ + variant: 'default' | 'filled'; + + /** + * Permiso requerido para ver el elemento de cuadrícula + */ + requiresPermission?: "owner" | "admin" | "editor" | "visitor"; + + /** + * Información del encabezado del elemento de cuadrícula + */ + header?: { + + /** + * Título del elemento de cuadrícula + */ + title: string; + + /** + * Icono del elemento de cuadrícula + */ + icon?: HeroIconName; + }; + + /** + * Información del cuerpo del elemento de cuadrícula + */ + body?: { + + /** + * Contenido HTML del elemento de cuadrícula + */ + html: string; + + /** + * Componente que se muestra en el elemento de cuadrícula + */ + components?: Record; + + /** + * Opciones de sanitización para el contenido HTML + */ + sanitizeOpts?: SanitizeOptions; + }; + }> | undefined; + + /** + * Si existe, el complemento tendrá su propia página de configuración + */ + settingsPage: { + + /** + * Campos según la especificación + */ + fields: SettingsField[]; + + /** + * Función que se ejecuta cuando se guarda la página de configuración + * + * Debe devolver una cadena si hay un error, + * de lo contrario devuelve true booleano para indicar éxito + */ + onSave: APIRoute; + } | undefined; + + /** + * Definición del tipo de página. Si está presente, el complemento quiere poder modificar el proceso de creación de páginas + */ + pageTypes: Array<{ + + /** + * Etiqueta que se muestra en el input select + */ + label: string; + + /** + * Identificador que se guarda en la base de datos + * @example + * // Un solo tipo de página por complemento + * 'studiocms' + * '@studiocms/blog' + * // Múltiples tipos de página por complemento (Usa identificadores únicos para cada tipo para evitar conflictos) + * '@mystudiocms/plugin:pageType1' + * '@mystudiocms/plugin:pageType2' + * '@mystudiocms/plugin:pageType3' + * '@mystudiocms/plugin:pageType4' + */ + identifier: string; + + /** + * Descripción que se muestra debajo del encabezado "Contenido de la Página" si se selecciona este tipo + */ + description: string; + + /** + * La ruta al componente real que se muestra para el contenido de la página + * + * El componente debe tener una prop `content` que sea una cadena para poder mostrar el contenido actual. + * + * **NOTA:** Actualmente, requiere que uses el id de formulario `page-content` para la salida de contenido. Tu editor también debe poder manejar el envío de formularios. + * + * @example + * ```ts + * import { createResolver } from 'astro-integration-kit'; + * const { resolve } = createResolver(import.meta.url) + * + * { + * pageContentComponent: resolve('./components/MyContentEditor.astro'), + * } + * ``` + */ + pageContentComponent: string; + }> | undefined; +}; +``` + +### Definiendo un complemento + +Para definir un complemento de StudioCMS, necesitas crear un objeto que se ajuste al tipo `StudioCMSPlugin`. Este objeto debe parecerse a lo siguiente, teniendo en cuenta que las siguientes propiedades son requeridas: + +- `identifier`: El identificador del complemento del archivo package.json. +- `name`: La etiqueta del complemento que se mostrará en el Panel de Control de StudioCMS. +- `studiocmsMinimumVersion`: La versión mínima de StudioCMS requerida para que el complemento funcione. + +Aquí hay un ejemplo de una definición de complemento de StudioCMS que incluye todas las propiedades requeridas y además proporciona una Integración Astro para realizar lógica personalizada: + +```ts twoslash title="my-plugin.ts" +import { definePlugin } from 'studiocms/plugins'; +import { AstroIntegration } from 'astro'; + +// Define las opciones para el complemento e integración +interface Options { + foo: string; +} + +// Define la integración Astro +const myIntegration = (options: Options): AstroIntegration => ({ + name: 'my-astro-integration', + hooks: { + "astro:config:setup": () => { + console.log('Hello from my Astro Integration!'); + } + } +}); + +// Define el complemento de StudioCMS +export const myPlugin = (options: Options) => definePlugin({ + identifier: 'my-plugin', + name: 'My Plugin', + studiocmsMinimumVersion: '0.1.0-beta.8', + integration: myIntegration(options), // Opcional, pero recomendado +}); +``` + +En este ejemplo, definimos un complemento de StudioCMS llamado `My Plugin` que requiere la versión `0.1.0-beta.8` o superior de StudioCMS. El complemento también proporciona una Integración Astro que registra un mensaje en la consola cuando se llama al hook `astro:config:setup`. + +Para más información sobre la creación de plugins, consulta la Guía [Haciendo Plugins Útiles](/es/plugins/extended) \ No newline at end of file