google / docsy

A set of Hugo doc templates for launching open source content.
https://docsy.dev
Apache License 2.0
2.57k stars 888 forks source link

feature: Ability to easily embed markdown docs NOT iframe #1716

Open dtzar opened 10 months ago

dtzar commented 10 months ago

I'm trying to find a way to embed GitHub markdown content with Hugo/Docsy like what works today with mdbook as seen here for the Cluster API project (source) and website render of that page. All that I can find is being able to use iframe with Docsy, which does not work since GitHub does not allow embed and likely will not produce desired behavior (feel/functionality). You can see this example deployed here (and equivalent source code). It's important I figure out a pattern which will work for not only the karpenter project, but also the CAPI project. The ideal goal would be to have a core shared set of documentation and then embedded documentation for each of the providers. Would really like to migrate CAPI* to Hugo/Docsy as this seems to be the standard and offers nicer functionality, but this is a blocker now for both projects (karpenter Azure website would be new).

fekete-robert commented 10 months ago

You can try to use something like this shortcode:

Invocation:

{{% include-remote-mdsnippet "https://github.com/bank-vaults/vault-operator/raw/main/VERSIONS.md" %}}

Shortcode (layouts/shortcode/include-remote-mdsnippet.html):

{{/* Fetch a remote markdown file (that doesn't include frontmatter) and include it in the page. */}}
{{ $url := .Get 0 }}

{{/* Do not change the indentation of the following block */}}
{{ with resources.GetRemote $url }}
{{ with .Err }}
    {{ errorf "%s" . }}
{{ else }}
{{- .Content | safeHTML -}}
{{ end }}
{{ else }}
    {{ errorf "Unable to get remote resource %q" $url }}
{{ end }}

I made it for one of my projects for a similar usecase, it doesn't do much, but might be enough for you.

fekete-robert commented 10 months ago

Alternatively, if you want to include files only from one or two repos, you can add them to your project as dependencies, mount the content of the repos somewhere, and include the files using readfile.

dtzar commented 10 months ago

Thanks for the quick response @fekete-robert! I think the include-remote-mdsnippet shortcode will work if I can find a way to remove the top header markdown content at the top of the file.

e.g.

---
title: "Development Guide"
linkTitle: "Development Guide"
weight: 80
description: >
  My description
---

Live example here

fekete-robert commented 10 months ago

Try this, it will handle the frontmatter, with some limitations:

{{/* Fetch a remote markdown file  and include it in the page. If the file has a frontmatter, define the marker of the frontmatter in the second parameter (defaults to "---"). If the content after the frontmatter includes the marker (for example, includes "---" as part of a markdown-formatted table) the content included will be incomplete. */}}
{{ $url := .Get 0 }}
{{ $marker := .Get 1 | default "---" }}

{{/* Do not change the indentation of the following block */}}
{{ with resources.GetRemote $url }}
    {{ with .Err }}
    {{ errorf "%s" . }}
{{ else }}
{{/*  Test for frontmatter */}}
{{ if hasPrefix .Content $marker }}
{{ $split := split .Content $marker }}

{{ with strings.Contains .Content $marker }} {{- warnf "Remote snippet includes frontmatter marker, content is truncated: %s" $url -}}
{{ end }}

{{/*  Output stuff after the frontmatter if a frontmatter was detected. */}}
{{- index $split 2 | markdownify | safeHTML -}}
{{ else }}
{{/*  Output the content of the file if no frontmatter was detected. */}}
{{- .Content | safeHTML -}}
{{ end }}
{{ end }}
{{ else }}
    {{ errorf "Unable to get remote resource %q" $url }}
{{ end }}

Also, I forgot to mention that if the file you want to include contains shortcodes, you have to invoke the include-remote-snippet shortcode with {{< ... >}} instead of {{% ... %}}

dtzar commented 10 months ago

That works, thank you! I can live without the table use case for now.👍 This would be nice to have as a default included feature for docsy IMO.

A further enhancement to the include-remote-mdsnippet would be if you could ingest just a named header section of the MD file versus the entire document for fine-grained control of what to embed.

If you want to consider this for being included in Docsy, then perhaps you can keep this issue open. If not, then feel free to close this issue out.

fekete-robert commented 10 months ago

Glad that it works :) I can submit it to Docsy, I'll create a PR for it.

I'll think about how to get only a specific section, but honestly I don't see an easy way to do that.

dtzar commented 10 months ago

Sounds good! I would say something like looking for a specific header code like ## my title until the next ##. I'm sure not an easy piece of code to write if it's possible.

froboy commented 2 months ago

Hey folks, I've been working on this and have cleaned up a few issues flagged in the original PR. Check it out. https://github.com/google/docsy/pull/1739#pullrequestreview-2139294730

I think my changes might be able to resolve some of what @dtzar was asking... I'm using it to trim a H1 from a README file that doesn't have a Markdown frontmatter, like this:

{{% include-remote-md "https://github.com/YCloudYUSA/yusaopeny_activity_finder/raw/5.x/README.md" "# Open Y Activity Finder" %}}