This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new 4360320a17 Add GisCus comments to docs
4360320a17 is described below

commit 4360320a1760ad084a1273a391b93086bb285797
Author: James Bognar <[email protected]>
AuthorDate: Sat Nov 15 10:20:44 2025 -0500

    Add GisCus comments to docs
---
 juneau-docs/docusaurus.config.ts              | 292 ++++++++++++++------------
 juneau-docs/src/components/GiscusComments.tsx |  67 ++++++
 juneau-docs/src/css/custom.css                |  31 +++
 juneau-docs/src/theme/DocItem/index.tsx       |  28 +++
 4 files changed, 286 insertions(+), 132 deletions(-)

diff --git a/juneau-docs/docusaurus.config.ts b/juneau-docs/docusaurus.config.ts
index 1faafb160e..c5ab52f6a3 100644
--- a/juneau-docs/docusaurus.config.ts
+++ b/juneau-docs/docusaurus.config.ts
@@ -11,12 +11,170 @@
  * specific language governing permissions and limitations under the License.
  */
 
-import {themes as prismThemes} from 'prism-react-renderer';
 import type {Config} from '@docusaurus/types';
 import type * as Preset from '@docusaurus/preset-classic';
+import type {GiscusProps} from '@giscus/react';
 
 // This runs in Node.js - Don't use client-side code here (browser APIs, 
JSX...)
 
+type GiscusThemeConfig = Partial<GiscusProps>;
+
+type ThemeConfigWithGiscus = Preset.ThemeConfig & {
+  giscus?: GiscusThemeConfig;
+};
+
+const giscusConfig: GiscusThemeConfig = {
+  repo: 'apache/juneau',
+  repoId: process.env.GISCUS_REPO_ID ?? 'MDEwOlJlcG9zaXRvcnk2NDczMjY2NQ==',
+  category: process.env.GISCUS_CATEGORY ?? 'Announcements',
+  categoryId: process.env.GISCUS_CATEGORY_ID ?? 'DIC_kwDOA9u9-c4CvzB6',
+  mapping: 'pathname',
+  reactionsEnabled: '1',
+  emitMetadata: '0',
+  strict: '0',
+  inputPosition: 'top',
+  theme: 'preferred_color_scheme',
+  lang: 'en',
+  loading: 'lazy',
+};
+
+const baseThemeConfig: Preset.ThemeConfig = {
+  // Replace with your project's social card
+  image: 'img/docusaurus-social-card.jpg',
+  algolia: {
+    // The application ID provided by Algolia
+    appId: 'DVIGEYTUK7',
+
+    // Public API key: it is safe to commit it
+    apiKey: 'db9fd10aa92e0ad212e08340e37293c0',
+
+    indexName: 'juneau_docsJuneau Website',
+
+    // Optional: see doc section below
+    contextualSearch: true,
+
+    // Optional: Specify domains where the navigation should occur through 
window.location instead on history.push. Useful when our Algolia config crawls 
multiple documentation sites and we want to navigate with window.location.href 
to them.
+    // externalUrlRegex: 'external\\.com|domain\\.com',
+
+    // Optional: Replace parts of the item URLs from Algolia. Useful when 
using the same search index for multiple deployments using a different baseUrl. 
You can use regexp or string in the `from` param. For example: localhost:3000 
vs myCompany.com/docs
+    // replaceSearchResultPathname: {
+    //   from: '/docs/', // or as RegExp: /\/docs\//
+    //   to: '/',
+    // },
+
+    // Optional: Algolia search parameters
+    searchParameters: {},
+
+    // Optional: path for search page that enabled by default (`false` to 
disable it)
+    searchPagePath: 'search',
+
+    // Optional: whether the insights feature is enabled or not on Docsearch 
(`false` by default)
+    insights: false,
+  },
+  navbar: {
+    title: 'Apache Juneau',
+    logo: {
+      alt: 'Apache Juneau',
+      src: 'img/oakleaf.svg',
+    },
+    items: [
+      {to: '/about', label: 'About', position: 'left'},
+      {
+        type: 'docSidebar',
+        sidebarId: 'mainSidebar',
+        position: 'left',
+        label: 'Documentation',
+      },
+      {to: '/downloads', label: 'Downloads', position: 'left'},
+      {to: '/security', label: 'Security', position: 'left'},
+      {to: '/apache', label: 'Apache', position: 'left'},
+      {
+        href: 'https://github.com/apache/juneau',
+        label: 'GitHub',
+        position: 'right',
+      },
+      {
+        href: 'https://github.com/apache/juneau/wiki',
+        label: 'Wiki',
+        position: 'right',
+      },
+      {
+        href: '/javadocs/',
+        label: 'Javadocs',
+        position: 'right',
+      },
+    ],
+  },
+  footer: {
+    style: 'dark',
+    links: [
+      {
+        title: 'Documentation',
+        items: [
+          {
+            label: 'About',
+            to: '/about',
+          },
+          {
+            label: 'Downloads',
+            to: '/downloads',
+          },
+          {
+            label: 'Javadocs',
+            href: '/site/apidocs/index.html',
+          },
+        ],
+      },
+      {
+        title: 'Community',
+        items: [
+          {
+            label: 'GitHub',
+            href: 'https://github.com/apache/juneau',
+          },
+          {
+            label: 'Wiki',
+            href: 'https://github.com/apache/juneau/wiki',
+          },
+          {
+            label: 'Mailing List',
+            href: 
'mailto:[email protected]?Subject=Apache%20Juneau%20question',
+          },
+        ],
+      },
+      {
+        title: 'Apache',
+        items: [
+          {
+            label: 'Apache Foundation',
+            href: 'http://www.apache.org/foundation',
+          },
+          {
+            label: 'License',
+            href: 'http://www.apache.org/licenses/',
+          },
+          {
+            label: 'Security',
+            href: 'http://www.apache.org/security',
+          },
+        ],
+      },
+    ],
+    copyright: `Copyright © ${new Date().getFullYear()} The Apache Software 
Foundation. Licensed under the Apache License, Version 2.0. Apache, Apache 
Juneau, and the Apache feather logo are trademarks of The Apache Software 
Foundation.`,
+  },
+  prism: {
+    theme: {plain: {}, styles: []}, // Use custom Eclipse colors instead of 
default theme
+    darkTheme: {plain: {}, styles: []}, // Use custom Eclipse colors for dark 
mode too
+    additionalLanguages: ['java', 'json', 'yaml', 'bash', 'properties', 'ini'],
+    defaultLanguage: 'java',
+  },
+} satisfies Preset.ThemeConfig;
+
+const themeConfig: ThemeConfigWithGiscus = {
+  ...baseThemeConfig,
+  giscus: giscusConfig,
+};
+
 const config: Config = {
   title: 'Apache Juneau',
   tagline: 'Universal toolkit for marshalling POJOs to a wide variety of 
content types using a common framework',
@@ -83,137 +241,7 @@ const config: Config = {
     ],
   ],
 
-  themeConfig: {
-    // Replace with your project's social card
-    image: 'img/docusaurus-social-card.jpg',
-    algolia: {
-      // The application ID provided by Algolia
-      appId: 'DVIGEYTUK7',
-
-      // Public API key: it is safe to commit it
-      apiKey: 'db9fd10aa92e0ad212e08340e37293c0',
-
-      indexName: 'juneau_docsJuneau Website',
-
-      // Optional: see doc section below
-      contextualSearch: true,
-
-      // Optional: Specify domains where the navigation should occur through 
window.location instead on history.push. Useful when our Algolia config crawls 
multiple documentation sites and we want to navigate with window.location.href 
to them.
-      // externalUrlRegex: 'external\\.com|domain\\.com',
-
-      // Optional: Replace parts of the item URLs from Algolia. Useful when 
using the same search index for multiple deployments using a different baseUrl. 
You can use regexp or string in the `from` param. For example: localhost:3000 
vs myCompany.com/docs
-      // replaceSearchResultPathname: {
-      //   from: '/docs/', // or as RegExp: /\/docs\//
-      //   to: '/',
-      // },
-
-      // Optional: Algolia search parameters
-      searchParameters: {},
-
-      // Optional: path for search page that enabled by default (`false` to 
disable it)
-      searchPagePath: 'search',
-
-      // Optional: whether the insights feature is enabled or not on Docsearch 
(`false` by default)
-      insights: false,
-    },
-    navbar: {
-      title: 'Apache Juneau',
-      logo: {
-        alt: 'Apache Juneau',
-        src: 'img/oakleaf.svg',
-      },
-      items: [
-        {to: '/about', label: 'About', position: 'left'},
-        {
-          type: 'docSidebar',
-          sidebarId: 'mainSidebar',
-          position: 'left',
-          label: 'Documentation',
-        },
-        {to: '/downloads', label: 'Downloads', position: 'left'},
-        {to: '/security', label: 'Security', position: 'left'},
-        {to: '/apache', label: 'Apache', position: 'left'},
-        {
-          href: 'https://github.com/apache/juneau',
-          label: 'GitHub',
-          position: 'right',
-        },
-        {
-          href: 'https://github.com/apache/juneau/wiki',
-          label: 'Wiki',
-          position: 'right',
-        },
-        {
-          href: '/javadocs/',
-          label: 'Javadocs',
-          position: 'right',
-        },
-      ],
-    },
-    footer: {
-      style: 'dark',
-      links: [
-        {
-          title: 'Documentation',
-          items: [
-            {
-              label: 'About',
-              to: '/about',
-            },
-            {
-              label: 'Downloads',
-              to: '/downloads',
-            },
-            {
-              label: 'Javadocs',
-              href: '/site/apidocs/index.html',
-            },
-          ],
-        },
-        {
-          title: 'Community',
-          items: [
-            {
-              label: 'GitHub',
-              href: 'https://github.com/apache/juneau',
-            },
-            {
-              label: 'Wiki',
-              href: 'https://github.com/apache/juneau/wiki',
-            },
-            {
-              label: 'Mailing List',
-              href: 
'mailto:[email protected]?Subject=Apache%20Juneau%20question',
-            },
-          ],
-        },
-        {
-          title: 'Apache',
-          items: [
-            {
-              label: 'Apache Foundation',
-              href: 'http://www.apache.org/foundation',
-            },
-            {
-              label: 'License',
-              href: 'http://www.apache.org/licenses/',
-            },
-            {
-              label: 'Security',
-              href: 'http://www.apache.org/security',
-            },
-          ],
-        },
-      ],
-      copyright: `Copyright © ${new Date().getFullYear()} The Apache Software 
Foundation. Licensed under the Apache License, Version 2.0. Apache, Apache 
Juneau, and the Apache feather logo are trademarks of The Apache Software 
Foundation.`,
-    },
-    prism: {
-      theme: {plain: {}, styles: []}, // Use custom Eclipse colors instead of 
default theme
-      darkTheme: {plain: {}, styles: []}, // Use custom Eclipse colors for 
dark mode too
-      additionalLanguages: ['java', 'json', 'yaml', 'bash', 'properties', 
'ini'],
-      defaultLanguage: 'java',
-    },
-  } satisfies Preset.ThemeConfig,
+  themeConfig,
 };
 
 export default config;
diff --git a/juneau-docs/src/components/GiscusComments.tsx 
b/juneau-docs/src/components/GiscusComments.tsx
new file mode 100644
index 0000000000..29d812482d
--- /dev/null
+++ b/juneau-docs/src/components/GiscusComments.tsx
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License"); you may not 
use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 
or implied.  See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+import Giscus from '@giscus/react';
+import {useColorMode, useThemeConfig} from '@docusaurus/theme-common';
+import type {GiscusProps} from '@giscus/react';
+import type {ThemeConfig} from '@docusaurus/types';
+
+type ThemeConfigWithGiscus = ThemeConfig & {
+  giscus?: Partial<GiscusProps>;
+};
+
+export default function GiscusComments() {
+  const themeConfig = useThemeConfig() as ThemeConfigWithGiscus;
+  const giscusConfig = themeConfig.giscus;
+  const {colorMode} = useColorMode();
+  if (!giscusConfig?.repo || !giscusConfig.repoId || !giscusConfig.mapping) {
+    return null;
+  }
+
+  const props: GiscusProps = {
+    repo: giscusConfig.repo,
+    repoId: giscusConfig.repoId,
+    mapping: giscusConfig.mapping,
+    category: giscusConfig.category,
+    categoryId: giscusConfig.categoryId,
+    term: giscusConfig.term,
+    theme:
+      giscusConfig.theme && giscusConfig.theme !== 'preferred_color_scheme'
+        ? giscusConfig.theme
+        : colorMode === 'dark'
+          ? 'dark'
+          : 'light',
+    strict: giscusConfig.strict ?? '0',
+    reactionsEnabled: giscusConfig.reactionsEnabled ?? '1',
+    emitMetadata: giscusConfig.emitMetadata ?? '0',
+    inputPosition: giscusConfig.inputPosition ?? 'bottom',
+    lang: giscusConfig.lang ?? 'en',
+    loading: giscusConfig.loading ?? 'lazy',
+    host: giscusConfig.host,
+    id: giscusConfig.id,
+  };
+
+  return (
+    <section className="giscus-comments" aria-live="polite">
+      <div className="giscus-comments__header">
+        <span className="giscus-comments__label">Discussion</span>
+        <hr className="giscus-comments__divider" aria-hidden="true" />
+      </div>
+      <p className="giscus-comments__description">
+        Share feedback or follow-up questions for this page directly through 
GitHub.
+      </p>
+      <Giscus {...props} />
+    </section>
+  );
+}
+
diff --git a/juneau-docs/src/css/custom.css b/juneau-docs/src/css/custom.css
index a07febc137..d39f492129 100644
--- a/juneau-docs/src/css/custom.css
+++ b/juneau-docs/src/css/custom.css
@@ -531,3 +531,34 @@ java-method-private::before { color: #CCB404; content: 
'\25c6\00a0'; font-weight
 java-method-annotation::before { color: #00ced1; content: '\25cf\00a0'; 
font-weight: bolder; font-size: x-small; }
 java-project::before { color: #ff6b35; content: '\1f4c2\00a0'; font-weight: 
bolder; font-size: x-large; }
 java-doc::before { color: #4a90e2; content: '\1f4d6\00a0'; font-weight: 
bolder; font-size: x-large; }
+
+.giscus-comments {
+  margin-block-start: 4rem;
+  margin-block-end: 4rem;
+}
+
+.giscus-comments__header {
+  display: flex;
+  align-items: center;
+  gap: 1rem;
+  margin-block-end: 0.5rem;
+}
+
+.giscus-comments__divider {
+  flex: 1;
+  border: 0;
+  border-top: 1px solid var(--ifm-color-emphasis-200);
+}
+
+.giscus-comments__label {
+  font-size: 0.85rem;
+  letter-spacing: 0.2em;
+  text-transform: uppercase;
+  color: var(--ifm-color-emphasis-500);
+}
+
+.giscus-comments__description {
+  margin: 0 0 1rem;
+  color: var(--ifm-color-emphasis-600);
+  font-size: 0.95rem;
+}
diff --git a/juneau-docs/src/theme/DocItem/index.tsx 
b/juneau-docs/src/theme/DocItem/index.tsx
new file mode 100644
index 0000000000..f00081db78
--- /dev/null
+++ b/juneau-docs/src/theme/DocItem/index.tsx
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License"); you may not 
use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 
or implied.  See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+import DocItem from '@theme-original/DocItem';
+import type {ComponentProps} from 'react';
+import GiscusComments from '@site/src/components/GiscusComments';
+
+type DocItemProps = ComponentProps<typeof DocItem>;
+
+export default function DocItemWrapper(props: DocItemProps) {
+  return (
+    <>
+      <DocItem {...props} />
+      <GiscusComments />
+    </>
+  );
+}
+

Reply via email to