diff --git a/apps/web/src/pages/plugins/[slug].astro b/apps/web/src/pages/plugins/[slug].astro
index dadb2787b..79c88348b 100644
--- a/apps/web/src/pages/plugins/[slug].astro
+++ b/apps/web/src/pages/plugins/[slug].astro
@@ -1,17 +1,19 @@
---
+import PluginIcon from '@/components/PluginIcon.astro'
import type { Plugin } from '@/config/plugins'
import { actions } from '@/config/plugins'
import Layout from '@/layouts/Layout.astro'
import { createSoftwareApplicationLdJson } from '@/lib/ldJson'
import * as m from '@/paraglide/messages'
-import { getSlug } from '@/services/github'
+import { getPluginsWithStars, getSlug } from '@/services/github'
import { defaultLocale } from '@/services/locale'
+import { getPluginDocsSlugs, resolvePluginDocsSlug } from '@/services/pluginDocs'
+import { Icon as AstroIcon } from 'astro-icon/components'
import type { GetStaticPaths } from 'astro'
import type { CollectionEntry } from 'astro:content'
import { getCollection } from 'astro:content'
import { getRelativeLocaleUrl } from 'astro:i18n'
import { marked } from 'marked'
-import PluginIcon from '@/components/PluginIcon.astro'
export const getStaticPaths: GetStaticPaths = async () => {
const pluginPosts: { [k: string]: CollectionEntry<'plugin'>[] } = {}
@@ -31,100 +33,58 @@ export const getStaticPaths: GetStaticPaths = async () => {
})
}
-// Get the plugin from the actions set
-const plugin = actions.find((item) => getSlug(item.href) === Astro.params.slug) as Plugin
+const locale = Astro.locals.locale ?? defaultLocale
+const plugins = getPluginsWithStars(actions)
+const plugin = plugins.find((item) => getSlug(item.href) === Astro.params.slug)
if (!plugin || !plugin.title) return new Response(`plugin is not found for: ${Astro.url.pathname}`, { status: 404 })
let tutorialPlugin = ''
const tutorialEntries = Astro.props.posts as CollectionEntry<'plugin'>[]
-const thisTut =
- tutorialEntries.find((i) => (i.data.locale || defaultLocale) === Astro.locals.locale) ?? tutorialEntries.find((i) => (i.data.locale || defaultLocale) === defaultLocale)
+const thisTut = tutorialEntries.find((i) => (i.data.locale || defaultLocale) === locale) ?? tutorialEntries.find((i) => (i.data.locale || defaultLocale) === defaultLocale)
+
+const normalizeTutorialHeading = (html: string): string => {
+ return html.replace(/^(\s*)
]*)>([\s\S]*?)<\/h1>/i, '$1$3
')
+}
+
if (thisTut?.body) tutorialPlugin = thisTut.body
if (tutorialPlugin.length > 0) {
const tmp = marked.parse(tutorialPlugin)
- if (typeof tmp !== 'string') plugin['tutorial'] = await tmp
- else plugin['tutorial'] = tmp
+ const tutorialHtml = typeof tmp !== 'string' ? await tmp : tmp
+ plugin['tutorial'] = normalizeTutorialHeading(tutorialHtml)
}
-plugin['githubStars'] = 0
-plugin['npmDownloads'] = 0
-
const tmp = marked.parse(`# ${plugin.title}\n\n${plugin.description}`)
if (typeof tmp !== 'string') plugin['readme'] = await tmp
else plugin['readme'] = tmp
-// const promises: any[] = []
-
-// Fetch npm package details to get npm downloads
-// const npmApiUrl = `https://api.npmjs.org/downloads/point/last-month/${plugin.name}`
-// promises.push(
-// fetch(npmApiUrl)
-// .then((res) => (res.ok ? res.json() : null))
-// .then((res) => {
-// if (res) plugin.npmDownloads = res.downloads
-// })
-// .catch(() => {}),
-// )
-
-// Fetch npm package details to get npm modified
-// const registryNpmApiUrl = `https://registry.npmjs.org/${plugin.name}`
-// promises.push(
-// fetch(registryNpmApiUrl)
-// .then((res) => (res.ok ? res.json() : null))
-// .then((res) => {
-// if (res) {
-// plugin.datePublished = res.time.created
-// plugin.dateModified = res.time.modified
-// }
-// })
-// .catch(() => {}),
-// )
-
-// Extract the GitHub repository owner and name from the URL
-// const githubUrlParts = plugin.href.split('/')
-// const githubOwner = githubUrlParts[3]
-// const githubRepo = githubUrlParts[4]
-
-// Fetch GitHub repository details to get GitHub stars
-// const githubApiUrl = `https://api.github.com/repos/${githubOwner}/${githubRepo}`
-// promises.push(
-// fetch(githubApiUrl)
-// .then((res) => (res.ok ? res.json() : null))
-// .then((res) => {
-// if (res) plugin.githubStars = res.stargazers_count
-// })
-// .catch(() => {}),
-// )
-
-// Update the item with fetched data
-// const readmeApiUrl = `https://api.github.com/repos/${githubOwner}/${githubRepo}/readme`
-// promises.push(
-// fetchWithToken(readmeApiUrl)
-// .then((res) => (res.ok ? res.json() : null))
-// .then((res) => {
-// if (res) {
-// const tmp = marked.parse(Buffer.from(res.content, 'base64').toString('utf-8'))
-// if (typeof tmp !== 'string') tmp.then((result) => (plugin.readme = result))
-// else plugin.readme = tmp
-// }
-// })
-// .catch(() => {}),
-// )
-
-// Await all the items to be fetched
-// await Promise.all(promises)
+const { localizedDocsSlugs, docsSlugs } = await getPluginDocsSlugs(locale)
+const docsSlug = resolvePluginDocsSlug(plugin, docsSlugs)
+const docsLocale = docsSlug && localizedDocsSlugs.has(docsSlug) ? locale : defaultLocale
+
+const formatCount = (count?: number): string => {
+ if (count === undefined) return 'n/a'
+ if (count >= 1000000) return `${(count / 1000000).toFixed(1)}M`
+ if (count >= 1000) return `${(count / 1000).toFixed(1)}k`
+ return count.toString()
+}
const { slug: id } = Astro.params
+const { title, description, githubStars, npmDownloads, href, name, tutorial, icon, author } = plugin as Plugin
+
+const npmHref = name ? `https://www.npmjs.com/package/${name}` : undefined
+const docsHref = docsSlug ? getRelativeLocaleUrl(docsLocale, `docs/plugins/${docsSlug}/`) : (npmHref ?? href)
+const docsIsExternal = !docsSlug
+const showRepoLink = href !== docsHref
+const showNpmLink = !!npmHref && npmHref !== docsHref
const content: { title?: string; description?: string; image?: string; author?: string; ldJSON?: Object } = {}
if (plugin.title) content['title'] = `${plugin.title} Capacitor Plugin: Install, Setup & Examples`
if (plugin.description) content['description'] = plugin.description
-// Create improved ldJSON using helper function for SoftwareApplication
-const pluginUrl = getRelativeLocaleUrl(Astro.locals.locale, `/plugins/${id}`)
+const pluginUrl = getRelativeLocaleUrl(locale, `/plugins/${id}`)
content['ldJSON'] = createSoftwareApplicationLdJson(Astro.locals.runtimeConfig.public, {
name: plugin.title,
@@ -132,110 +92,142 @@ content['ldJSON'] = createSoftwareApplicationLdJson(Astro.locals.runtimeConfig.p
url: pluginUrl,
applicationCategory: 'DeveloperApplication',
operatingSystem: 'iOS, Android',
- softwareVersion: '1.0.0', // Default version as plugin doesn't have version property
downloadUrl: plugin.href,
- aggregateRating: plugin.githubStars
- ? {
- ratingValue: Math.min(plugin.githubStars / 100, 5), // Normalize stars to 5-star scale
- reviewCount: plugin.githubStars,
- }
- : undefined,
})
-
-const { title, description, githubStars, npmDownloads, href, name, tutorial, icon } = plugin
---
-
-
-
-
-
-
-
-
-
-
- {icon &&
}
-
- {title}
-
-
-
- {description}
-
- {
- githubStars && (
-
- )
- }
- {
- npmDownloads && (
-
-
NPM Downloads {npmDownloads}
+
+
+
+
+
+
+ ←
+ Back to plugins
+
+
+
+
+
+ {
+ name && (
+
+ {name}
+
+ )
+ }
+
Tutorial
+
by {author}
+
+
+
+ {icon &&
}
+
+
+ {title}
+
+
+ {description}
+
- )
- }
-
+
+
-
+
+
-
- {tutorial && }
+
+
+ {
+ tutorial && (
+
+
+
+
+
Guide
+
+ {m.tutorial_on({}, { locale })} {title}
+
+
+
+
+
+
+ )
+ }
-
-