Giter VIP home page Giter VIP logo

flowershow's Introduction

🌷 Flowershow template

Publish your Obsidian notes (or any markdown), beautifully. For free, no coding.

Flowershow is an open-source tool for easily converting your markdown files into an elegant website. It's built on a standard, modern web stack – React, Next.js, and Tailwind and shipped with a basic default theme to get you started with just a few clicks.

  • Crafted for Obsidian, Flowershow works with your Obsidian vault out of the box. No need to modify the syntax or change the file layout. If you're not an Obsidian fan, Flowershow can be used with any CommonMark or GFM files.
  • Elegant and functional default theme with basic front page and navbar.
  • Easy to tweak and extend with custom page layouts and custom React components, that can be used within your markdown.
  • Backed by a team of data geeks, who love Markdown, and are passionate about sharing knowledge and ideas with others.

For full feature list see https://flowershow.app/#features

obsidian-vs-flowershow

Docs

https://flowershow.app/docs/

Use with Obsidian Flowershow plugin

You can use this template together with the Flowershow Obsidian Plugin. See the README in the plugin repo for information on how to set it up.

Quick clone and deploy

With Vercel:

Deploy with Vercel

Forum

https://github.com/flowershow/flowershow/discussions

Chat

Come find us on Discord: https://discord.gg/cPxejPzpwt

Contributing

If you want to contribute, you are more than welcome! You can start by checking our project backlog.

If you have an idea for improvement, and it doesn't have a corresponding issue yet, simply submit a new one.

If you'd like to work on an existing issue:

  1. Fork the main repository.
  2. Clone the forked repository to your machine.
  3. Create a feature branch (e.g. 50-update-readme, where 50 is the number of the related issue).
  4. Commit your changes to the feature branch.
  5. Push the feature branch to your forked repository.
  6. Create a Pull Request against the original repository.
    • add a short description of the changes included in the PR
  7. Address review comments if requested by the reviewers.

flowershow's People

Contributors

aabounegm avatar abhishekgahlot avatar anuveyatsu avatar balaji-dutt avatar demenech avatar dependabot[bot] avatar gutts-n avatar homostellaris avatar khalilcodes avatar mohamedsalem401 avatar nosovk avatar olayway avatar philippedupreez avatar rdimaio avatar rufuspollock avatar siam1113 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

flowershow's Issues

Empty pages cause build error

Not sure if we should fix this or add a note somewhere in the docs, that there shouldn't be any empty pages in the content dir.

What happens?

Adding an empty page to the content dir (content/docs/roadmap.md in this case) results in a build error:

> Build error occurred
Error: Export encountered errors on following paths:
        /[[...slug]]: /docs/roadmap

image

Notes

This is because json file generated by Contentlayer for this page, has code value equal to an empty string.

{
  "layout": "docs",
  "body": {
    "raw": "",
    "code": ""
  },
  ...
  "type": "Page",
  "url": "roadmap"
}

Notes

The error is thrown in useMDXComponent hook imported from contentlayer/hooks. Since code in case of empty md files will be an empty string, the function created with new Function(...Object.keys, code) will have no body, so it will implicitly return undefined.

https://github.com/contentlayerdev/contentlayer/blob/9c19fbd349eb3c677753ac4c5b6323115e22d31c/packages/next-contentlayer/src/hooks/useMDXComponent.ts#L22-L30

Current workaround

const defaultCode = `
return {default: () => React.createElement('div', null, '')}
`;

const pageCode = body.code.length > 0 ? body.code : defaultCode;
const MDXPage = useMDXComponent(pageCode);

Add anchor links to headings

In Obsidian you can create internal links that point to a specific heading in a given file, by adding # and the name of the heading to the link. E.g. [[docs/roadmap#Callouts]], would point to Callouts heading in /docs/roadmap.md.
Such links to headings are correctly converted to URL's (in this case it would be [root_URL]/docs/roadmap#callouts) but since headings at the moment don't have ids, #callouts has no effect.

See https://github.com/rehypejs/rehype-autolink-headings

Acceptance

  • Headings get id/anchors (olayway:) this is easily done with rehype-slug and rehype-auto-link-headings
  • they are compatible with what obsidian generate (olayway:) yes, tested with these two packages
  • they are compatible with remark-toc e.g. with #27 (olayway:) yes, tested with these two packages and remark-toc
  • they are compatible with what we do in #95 (olayway:) I'd say it's not a matter of compatibility; it's the matter of populating the RHS ToC with headings (that we have added ids and anchors to) from each page (see notes below)
  • working links to a specific heading within a given page, e.g. [[roadmap#Planned features]] (olayway:) yes, tested with these two packages
  • working links to a specific heading within a given page with a custom name, e.g. [[roadmap#Planned features|Work in progress...]] (olayway:) yes, tested with these two packages

Notes

rehype-slug, rehype-autolink-headings, and remark-toc have been tested on this branch: https://github.com/flowershow/flowershow/tree/47-headings-links

  • see headings on any page - they have [ # ] icon above them that links to themselves as well as ids (this is just a test, not styled yet)
  • see table of contents on /docs/mdx page
  • see testing obsidian links to headings on /test/links-to-headings page

Pros of using the above 3 packages

It is very simple (almost done on the above test branch, only headings require some styling) and works just like that.

Cons

These packages allow for minimal customization. Even styling headings to achieve the hover-over effect with [ # ] icon like tailwind has is not that simple and will require some workaround (or even a slightly different result).

Additionally, we still would need a way to populate the RHS ToC (#95) with headings from the current page, which would require parsing the page once again in search for headings (sth that is already done twice by rehype-slug and rehype-autolink-headings), extracting their slugs and somehow making them available to the RHS ToC. Tailwind is doing it the custom way - using custom Heading components that (apart from adding ids and links) register/unregister themselves to/from the ToC.

My analysis of Tailwind's solution: https://github.com/datopian/product/blob/main/notes/tailwindcss-website-toc.md

Proposed solution

Since adding links and in-markdown ToC is extremely simple using the 3 packages mentioned above, I'd use them for now and start working on custom solutions while working on RHS ToC.

Google Analytics improvements

Already have this roughly working. However one issue seems to be that it is tracking page titles rather than page urls at least on evidence of web3 site (? to be confirmed)

Acceptance

  • Setup
    • Tracking page urls (instead of or as well as page titles) βœ…2022-07-22 INVALID - actually tracking page urls. Just that page names show by default. See screenshost just below showing the ability to select page urls in GA
  • Documented
  • Deployed on flowershop.app βœ…2022-07-21 and tested it worked 2022-07-22

image

Tasks

  • Get code
  • Add to config
  • Deploy
  • Test

[epic] Flowershow website v0.1 (landing page)

Simple, elegant landing page that explains what the product is and provides a way to get started (or signup if that is not ready) so that we can start sharing/testing with people and get early interest

Acceptance

  • Landing page website in site folder 🚧2022-06-26 in progress atm.
    • uses default template from templates/default
    • Hero section
    • CTA in hero section βœ… 2022-07-26 #72
    • Link to github in navbar (new config option like we had on web3??) βœ…2022-07-19 working
  • Site deployed βœ…2022-06-26 working on netlify at https://flowershow.app
  • Add an β€œAlpha” button to navbar like contentlayer has βœ… 2022-07-26 #73

βœ…2022-07-28 All DONE

image

Tasks

  • Content
  • Implement theme (focus on landing page) #23
    • Depends on #8
  • CTA: Get updates - with Subtext: Get short updates when we release new features (like web3 but shorter) βœ… 2022-07-26 #72

Content

  • brainstorm ideas e.g. value props, tagline, description βœ…2022-06-22 see copy draft doc
  • distill 🚧2022-06-22 50%??
  • refine into slides 🚧2022-07-08 slides in gdocs
    • Hero/Summary
      • Header
      • Subheader
      • CTA

CTA

Options:

  1. 2 buttons
  2. Sign up form
  • β€œGet Started” => sign up for flowershow form
  • Get updates
    • Subtext: Get short updates when we release new features
  • Sign Up
    • Subtext: sign up to get notified when it’s ready

Option 1) 2 buttons: "Get Started" and "Learn more".

"Get started" should lead to a form to be notified when we launch properly (brief blurb about "launching soon.

image

Option 2) Sign up to get notified email

Like on web3 or here on tailwindui

image

Setup

  • Initial setup βœ…2022-06-26 most of this in #1 as part of dogfooding so see there
  • Deployment

Deployment

  • Deploy e.g. on cloudflare pages ❌2022-06-26 running into issues with root directory and the ability to set content directory. Builds fine using root directory as templates/default for the default template but using the FLOWERSHOW_CONTENT config to point to the content directory is not working
  • OK so the issue is that my guess is that cloudflare pages limits access of the build to stuff outside of the root directory in some way βœ…2022-06-26 ultimately realized no real way to do this with cloudflare pages other than having everything inside the root / build directory which doesn't really work for our use case or our planned use case for users. However, netlify does allow symlinking so going with that
  • => we have to go the symlink root whereby we symlink content folder into the nextjs template LATER: on reflection no reason this would work any better. cloudflare pages doesn't allow access outside root folder whether symlink or otherwise. That said i think this symlinking actually makes sense given the config file location issues in #7
    • if so, do we a) just symlink content back into templates/default or make an actual copy (rather than symlink) of templates/default into site/.flowershow
    • KISS => just symlink into templates/default for now
      • However, note this may make installing from that template behave weirdly e.g. there will be loads of stuff in content. πŸ€”
      • For the record: tried a semi-hack where still .flowershow/templates/default but made it a real folder and then symlinked subcontent but that ran into loads of issues which i think relate to nextjs not allowing imports from outside root directory see e.g. vercel/next.js#22867 + vercel/next.js#706
  • Deploy on netlify βœ…2022-06-26 working after restricting node version - see comment below.

Backlinks

Show backlinks for a page (optional / configurable). Backlinks are all the pages that link to this page.

Multiline blockquotes support

In Obsidian, you can create multiline blockquotes by returning at the end of the first line and starting the next one with > (which is added automatically in Obsidian by hitting enter while being on the end of the first line.)

Raw example:

> Roses are red,
> violets are blue.

How it renders in Obsidian:
image

How it renders here on GitHub:

Roses are red,
violets are blue.

How it renders in Flowershow:
image

What works

Adding two spaces at the end of the first line.

Raw example:

> Roses are red,  
> violets are blue.

How it renders in Obsidian:
image

How it renders here on GitHub:

Roses are red,
violets are blue.

How it renders in Flowershow:
image

Config can be overridden by user

When setting up my site I want to change configurable parameters so that I can change things without having to code

Also want to do this without getting into core code so that core remains update-able => separate config

Acceptance

  • Can set a bootstrap config variable from environmental variables e.g. FLOWERSHOW_CONTENT DONE. No need for dotenv as nextjs already supports .env / .env.local etc UPDATE 2022-07-19 we are going to remove this as not necessary for now
  • Can set configuration from config file (TODO: location? is it .flowershow/config.js or simply config.js in content folder ...) βœ…2022-07-19 we have gone (only feasible) path afaict of having a hard-coded config.js in content/config.js

Bonus (separate)

  • Merge navLinks into siteConfig (no need for them to be separate) βœ…2022-07-04 DONE

Tasks

  • Environment based configuration - maybe just for a bootstrap variable
  • File based configuration for the rest βœ…2022-06-25 this turns out to be much more complex than thought so went for a very simple option of putting in a userConfig.js which is problematic in that user will have to get into the flowershow repo but is sort-of upgradeable
  • Move content/userConfig.js to content/config.js βœ…2022-07-19 PR #52
  • Remove using env to set content folder in siteConfg.js and highlight in comments that it shouldn't be changed. βœ…2022-07-19 PR #52

Notes

  • Simplest to start with would be environment variables ...
  • Better would be yaml or json config that user can have in the root of their project called e.g. flowershowconfig.yaml
  • Easiest starting point might be working out how to override from env variables see e.g. https://github.com/motdotla/dotenv

On reflection env variables make sense for developers and therefore for app related stuff but users are unlikely to use them and instead will want a file.

That suggests that for the app config we really only need one config variable set by environment which is the location of the config file -- or the location of the content directory if the config file is always in a given location in that directory (e.g. config.yml

File-based configuration - the saga

Allowing for a user config file turns out to be much more complex thank I thought because it requires loading config from a dynamic location which isn't permitted by nextjs outside of getStaticProps (and hence not in e.g. siteConfig.js where we'd like to do it)

Attempt 1

Try something like this:

import * as path from 'path'
const configPath = path.resolve(content, 'config.js')Β  Β 
const userConfig = await import(configPath)
const siteConfig = Object.assign({}, defaultConfig, userConfig)

As you get an error:

Module parse failed: Top-level-await is only supported in EcmaScript Modules

And if you try to fix that you get errors with webpack compilation e.g.

Critical dependency: the request of a dependency is an expression

Attempt 2

What about if we were just loading json or yaml it may be easier ...

import * as path from 'path'

import * as fs from 'fs'

const configPath = path.resolve(content, 'config.json')

const userConfig =Β  fs.existsSync(configPath) ?Β  JSON.load(fs.readFileSync(configPath)) : {}

But this runs into the issue that we can't use fs outside of getStaticProps etc ...

So what to do?

Options

  • Get config in e.g. getStaticPaths or _app.js (or similar) and pass down to layouts
    • There's attraction to this as import from a given location is fragile with plugins anyway (e.g. can plugins easily find the file)
    • Do same but wrap in a lib/config.js
    • 🚩 have to be aware that there is no nice way in nextjs to load common data for whole app anywhere vercel/next.js#10909 (reply in thread)
  • Quick and dirty: just have userConfig.js in config directory
    • But how does this get overridden? If it does not

Search functionality in flowershow.app website

When on flowershow website i want to quickly search for information

Acceptance

  • Search in navbar a la tailwindcss.com etc βœ… PR #81
  • Docs for this feature βœ… done /docs/search
    • user section explaining what search is and maybe short screenshot.
    • admin section explaining how to configure (e.g. what fields need to be set where)

Tasks

  • Register on algolia docsearch βœ…2022-08-08 did this and have stuff for flowershow.app
  • Implement Search component and use
  • Docs

Social Buttons e.g. in navbar or footer

Like we have on web3 etc

image

2 parts here:

  • Having the content / data ⏭️ get a standard structure for this in config e.g. following timlrx or our setup we used in web3
  • Where to use it (automatically) ⏭️ suggest footer (i.e. for each value set we use it)

Do we provide standard values for at least the icons?

Acceptance

  • Docs for how to use this e.g. /docs/social-buttons
    • what is the functionality
    • how to add to config
    • how it will auto show-up in footer
    • using it elsewhere in your app e.g. in markdown
  • Set it up for main site
social: [
	  github: '',
	  twitter: '',
	  facebook: '',
	  youtube: '',
	  linkedin: 'https://www.linkedin.com',
	  podcast: 
	  forum: 
	  chat: 
]

Use changesets

Set up https://github.com/changesets/changesets for this repo and briefly document it into the developer workflow

Good recent setup instructions https://dnlytras.com/blog/using-changesets/

Acceptance

  • We are using changesets to track changes e.g. one changeset example
  • Automating doing releases and pushing to npm via github actions (?)
  • short docs on our use of changests in developer docs e.g. https://flowershow.app/docs/developers

Tasks

  • Quick research on how to do this
  • Recommend whether to proceed (e.g. are benefits worth the costs)
  • Next steps ...
  • ...

MDX support including components and data

To make richer markdown pages we want MDX and be able to use components and data in the page e.g.

import MyComponent from '@components/MyComponent'

const orgs = [ 'abc' ]

# Hello world

Acceptance

  • [x] A demo page working using a component and data that is passed in e.g. <MyCoolComponent value={props.mydata} /> 2022-08-11 (olayway:) we're no longer using demo pages
  • Document these in a new page on flowershow.app e.g. docs/howto-use-components-in-your-markdown βœ… 2022-07-07 see https://flowershow.app/docs/howto-use-components-in-your-markdown | 🚧 2022-08-11 (olayway:) 80% done, will include some context about MDX and how to import custom components/external data but also how to define them locally in a markdown file | 2022-08-15 done in PR #89
    • How do we use components in the mdx file 🚧 2022-08-11 (olayway:) 80% done | 2022-08-15 done in PR #89
    • How do we pass data into the mdx file and use in components have to add the data in pages/[[slug]].js | 🚧 2022-08-11 (olayway:) 80% done + no, you don't have to add the data in pages/[[slug]].js - you can import it from external file or define it directly in markdown | 2022-08-15 done in PR #89
  • Research if we really can import components and hero - see [Rufus comment below] βœ… 2022-08-22 (olayway:) yes, we can(#20 (comment))
    • Report on whether it works or not by trying out a demo in our case (key will probably be getting import path right) βœ… 2022-08-22 (olayway:) currently you can see it working here

BONUS: find out if contentlayer supports direct imports in the MDX file e.g.

import MyComponent from '@components/MyComponent'

# Hello world

🚫 tried but not working and could not find, but next-mdx-remote does so I may be missing something ? βœ… 2022-08-22 (olayway:) yes, tested and works -> Contentlayer supports MDX and ESM import/export statements are part of MDX standard syntax, currently you can see it working here

Tasks

  • [ ] Demo page of component with props @ /demo 2022-08-11 (olayway:) we're no longer using demo pages
  • Documentation at notes/howto-use-components-in-your-markdown 🚧 2022-08-11 (olayway:) 80% done; my idea is to put it in /docs/mdx cuz I'm adding a bit context about MDX + it will include sections about: 1) how you can import custom components 2) how you can define components within markdown file (no importing) 3) how you can import data 4) how you can define data(variables) directly in your markdown | 2022-08-15 done in PR #89

Using components

https://github.com/contentlayerdev/website/blob/main/src/pages/docs/%5B%5B...slug%5D%5D.tsx

Options:

  • 🚫 add component in components/MDX.js and use it in markdown eg. <MyComponent /> 2022-08-11 (olayway:) no, you don't have to do that, but of course, you can - e.g. for the component you use across a lot of your md files so it makes sense to make them available globally
  • import components directly in mdx not working. (tried with .mdx file too) 2022-08-11 (olayway:) works but you have to change React components' file extension from .js to .jsx (for reference, see comments from Contentlayer team on the issue we've submitted)

Passing props

Can pass arguments to MDX renderer and access as props? βœ… YES

❕2022-08-11 (olayway:) You can also define data directly in your markdown files or import them from JSON file into your markdown files and then pass it as props to your components

Add as global props ...

// in pages/[[...slug]].js

...
const Component = useMDXComponent(body.code, { globalProps })
...

See https://spectrum.chat/mdx/general/resolved-how-to-use-props-or-variables-with-mdx-files~3cd95635-1d93-440e-9802-7571cacfd578 - gatsbyjs/gatsby#17551

Comments in Markdown support

Would be nice to support comments that do not render.

e.g. Obsidian support this:

image

Flowershow currently does not but supports MDX comments (?):

image

Given we have MDX you could just use html/jsx commenting which mdx supports i believe see e.g. mdx-js/mdx#184

My suggestion here is we just add a page to document this e.g. docs/comments

Acceptance

  • docs page on comments e.g. docs/comments with example/test

Tasks

  • Test that MDX supported comments are indeed supported e.g. html or jsx style
  • Put up a docs page

Broken links to index pages (when using obsidian)

What happens?

Internal links created in Obsidian, that point to some_folder/page_name are converted - as expected - to URLs which end with some_folder/page_name. Unfortunately, index.md pages are treated exactly the same, so resulting URLs end with some_folder/index, which results in 404.

Example:
In docs/index page, I'm creating an internal link to demo/index page, like so: [[demo/index]]. A resulting anchor tag will point to [...]/demo/index, instead of [...]/demo.

Temporary workaround

Manually remove /index part from [[demo/index]] link automatically created by Obsidian, and leave [[demo]] only.

Research how we can build a richer metadata database to build site from

Research how we can build a richer metadata database to build site from e.g. that includes forward/back links so that we can display that information

UPDATE 2023-03-24: we have done extensive research and arrived at a solution which is to build our own sqlite-based metadata database termed markdowndb. This effort is already well advanced and we are actively using a prototype markdowndb in live projects

Tasks

Notes

Backlinks are complex as they will require processing all documents.

Assets folder support

When I create stuff in content/assets (hard-code for now) i want that to show up on the site at /assets so my links work in my markdown

FUTURE: assets configurable and set up as part of scaffolding

Acceptance

  • assets folder in flowershow.app works βœ…2022-07-21 this is now working.
  • rough docs for this (for now can explain you need to manually symlink and in future you do X) βœ…2022-07-22 see https://flowershow.app/docs/essentials/assets

Tasks

  • Symlink in this repo
  • Add docs

Use typescript

Shall we use typescript? Pros and cons please ... UPDATE: we will trial it ...

Acceptance

  • Made a choice about trialling
  • Do basic setup (what is required?)
  • Start using
  • Summarize experience and whether we go 100%

Tasks

  • migration analysis
  • switch from JS to TS in CLI package done #300
  • switch from JS to TS in the template package

Analysis

Since TS is a superset of JS, migration to 100% TS codebase can be gradual. Also, Nx has native TS support so all the workspaces and projects in our repo will already include basic ts.config.json files and should already support TS out of the box.

Suggested approach

  • Add support for TS to the existing codebase
    • ts compiler configurations,
    • add build step for the CLI,
    • start creating d.ts declaration files to enable type-checking of the existing JS code by the TS compiler (the additional benefit at this point is auto-completion support in code editors)
    • write all NEW files in TS
  • Slowly start refactoring existing JS files to TS.

Potential issues

Making template package work with tsconfig.json file instead of our original jsconfig.json

TL:DR:
npm run dev --> Next.js sees the tsconfig.json file and adds jsx: preserve compiler option (or overrides it) --> Contentlayer's esbuild picks up the changed tsconfig.json file --> JSX in md files is not converted to JS --> errors!

Problem: contentlayer is not converting JSX to JS when used with Next.js + tsconfig.json file.

Context: When Next.js sees the tsconfig.json file in the project (template), it overrides some of the values that are required to make Next.js work as expected and they don't have the option to opt out of it. One of these properties is jsx, which by default is set to react, but Next.js will change it to preserve.

react: Emit .js files with JSX changed to the equivalent React.createElement calls
preserve: Emit .jsx files with the JSX unchanged

Next.js does it because they claim they have better way of converting JSX to JS, so they don't want the ts compiler to do this. However, the same ts.config.js file will be picked up by Contentlayer's esbuild and so it will not convert JSX to JS with React elements.

Upgrade old nextjs-tailwind-mdx app to use contentlayer

Currently using old-style explicit mdx loading. We want to use contentlayerdev now.

Acceptance

  • contentlayer implemented Done in templates/default
    • one standard type with no required fields Done with one optional field title
    • used by [...slug].js Done
  • BONUS: content directory comes from siteConfig.js as single string or array (with brief note on what it is) Done

Tasks

Can copy/paste from previous efforts e.g. https://github.com/life-itself/web3/blob/main/site/contentlayer.config.ts

Some ideas relating to the procedural generation of visual elements associated with notes/concepts

Greetings!

This looks like a really cool project! Thanks for making it open-source from the get-go!

I just wanted to share a few ideas relating to the possible application of viz/proc-gen, discussed briefly with @rufuspollock.

Basic thoughts:

  1. It could be useful to associate each note (or topic/entity in an eventually knowledgebase implementation) with some visual element.
  2. In addition to just making for a (potentially) more fun and playful experience, persistent visualizations associated with commonly-considered ideas can be a helpful way to reinforce the memory.
  3. 2d/3d procedural generation could be used to generate such visual entities. three.js is great for both of these.
  4. If one can divide notes up into meaningful semantic groups (e.g. via clustering of document embeddings), then a color could be assigned to each semantic group and used for the procedurally-generated elements.
  5. There are different types of visual elements one could imagine generating (e.g. trees, planets, etc.), but, given the theme of this tool, a good candidate might be to procedurally generate flowers and other plants as part of a garden.
  • ex. here (not procedurally-generated afaik, but a pretty reference example)
  1. One could further imagine "growing" plants/flowers in the garden in proportion to the amount of activity the note/topic gets.

Some of these ideas might not be relevant at all to your goals, but it's something to consider, perhaps. 🌷

Keep up the great work!
Keith

Configurable layouts for pages

Allow for (at least) 2 different layouts: a) "content/documentation" (classic markdown style) b) "landing" (or just "unstyled") which is pretty much a raw page with navbar and footer ie. unstyled

Acceptance

  • can set layout: {name} in frontmatter of a markdown page and uses that layout from components (ignorecase is supported e.g. layout: abcmatcheslayouts/Abc.jsx` βœ…2022-06-28 in #15. Two layouts. @khalilcodes one question is whether case insensitive (not a big deal if not)
  • One default one (maybe configurable??) that is used if not specified. Suggest docs is the default. βœ…2022-06-28 docs is the the default
  • Two layouts: unstyled and docs βœ…2022-06-28 working
  • Tests (at least "demo tests") very basic tests. need something better if we can

Tasks

...

Testing v0.1

Let's start testing our site asap with e2e tests both for local text and CI.

Questions

  • do we use cypress or playwright? any works, let's use playwright

Acceptance

  • One passing e2e tests βœ… 2022-06-27
  • CI setup (??) - this could be left to later if complex

Tasks

Notes

Things to test

  • Root index page (from markdown) βœ… 2022-06-27
  • Adding a js page somewhere (and it still works with catch-all route)
  • About page
  • nested index page etc βœ… 2022-06-27

[epic] Flowershow MVP v0.1

Working app that is useable enough to power the website of flowershow itself so that we can validate the approach

  • Key aspect is the template
  • Command line is nice but secondary

Acceptance

  • flowershow repo βœ…2022-07-01 or earlier
  • default template working βœ…2022-07-12 it is working
  • flowershow.app running off that default template βœ…2022-07-20 all done. See https://flowershow.app/

Dogfooding the app

  • Have a front page and other pages use markdown βœ…2022-07-12 have lots of page e.g. https://flowershow.app/docs
  • Nice landing page (still powered by markdown) βœ…2022-07-20 all working. See #23 for screenshot etc.

Features

  • tailwind support
  • Markdown support
  • MDX support
  • Basic site config
  • Basic theme e.g. navbar and footer 🚧2022-07-12 what do we mean by this? configuration thereof?
  • Analytics - google - this could be first test for componentization (or maybe just live with default for now)
  • Docs and Raw layout 🚧2022-07-12 DONE but needs proper documentation

Bonus:

  • SEO support
  • theme customization

Pre-questions

  • Do we try and do in component/compositional way or just do all in one for now? βœ…2022-06-22 go all in one route though compositional where we can
    • Work out how we do adding stuff if we go that route.
  • Do we work in portal.js repo or in new flowershow? βœ…2022-06-22 go for flowershow as one repo for one thing and we can have site alongside

Tasks

Dogfood a bit - boot the flowershow website using the template

try to do it all in markdown (or close to!)

  • symlink templates/default into .flowershow/templates directory
    • What about siteConfig type stuff though
  • Then set content directory as path ../../ βœ…2022-06-24 actually because of symlink setup in our case did ../../site/ -- that's ok and in all other cases would be ../../
  • Being able to set the home page
    • Remove default pages/index.js as will conflict with real index page
    • Want index.md picked up as "index" file for a folder
    • (?) Want README.md picked up as index file for a folder ❌2022-06-24 WONTFIX for now as not that important. More for compatibility with eg. github viewer etc

Landing page (nice)

Asides / Bonus

  • What about assets folder? => have to symlink into flowershow
  • customizable layouts per markdown page?? (future?) #8
  • How do we do config overriding?? Several options. Most basic and standard is environmental variables. #7 ❌2022-07-12 WONTFIX for now as painful. Rather use convention over configuration. Everything is in content folder.
  • How do we expose config variables to markdow pages 🚧2022-07-12 this is the same as #20 issue about data passing. For now we defer this
    • for the mdx system we are using how do we insert variables into the scope of the page ... βœ…2022-07-12 Same as previous point

Notes

Rufus

  • Treat "site" like a project a user would create => content at the root??
    • could make things a bit easier for ourselves by still having content in a subdirectory??
  • There is some advantage to "one level of indirection" even if that indirection is inside flowershow setup
    • Why? Because nextjs is kind of picky about where stuff goes as is contentlayer e.g. js files have to be in pages directory, contentlayer doesn't allow us to do (what??)

Layout of site (template for project sites)

Inside site/

# this will even be symlinked in our case
# in normal cases would be installed (via git even so easy to upgrade)
.flowershow/templates/default  # not touched by user (so we can keep changing)
.flowershow/content

index.md
my-other-file.md
my-directory/index.md => my-directory (not my-directory/index)
my-directory/abc.md 

# if i'm using obsidian ... this needs to end up in public
assets/

[Epic] Blog support

What is a blog?

  • [Technical] A page with set of posts usually shown in reverse order
  • [User Needs] show news / updates. usually more polished or "featured" content (not so much a notebook)

Note: the functionality of a blog and a news section are pretty much identical from a technical perspective. So in everything we write here about blogs also can be used to implement news.

Acceptance

Tasks

Update github README

A bunch of people will come to the github and so worth having some reasonable content in the README along with clear pointers to the docs.

Acceptance

βœ… 2022-07-28 #76

  • README is updated βœ…
  • has a reasonable intro βœ…
  • Screenshot βœ…
  • Link to docs βœ…
  • Contribution instructions βœ…

Mermaid support

When creating markdown pages I want to add mermaid-syntax diagrams so that I can display nicely rendered diagrams

https://mermaid-js.github.io/mermaid/#/

Acceptance

```mermaid
graph TD

a --> b
\```

Tasks

  • research options e.g. existing remark plugins
  • Select one to try
  • Try it
  • Deploy
  • Document
  • ...

Notes

We want a solution that renders client side (we do not want to render svg and insert)

Options

  • https://github.com/temando/remark-mermaid 2022-07-26 this looks pretty promising for what we want
    2022-08-02 summary: adding as a plugin in remark just throws error as seen in notes below
  • https://github.com/sjwall/mdx-mermaid - Plug and play Mermaid in MDX
    2022-08-02 summary:
    • adding as a plugin in remark just outputs the component as a string.
    • Adding the component in MDX components client side ie. Pre.js is complicated as rehype-prism-plus converts the graph to span elements and <Mermaid char={...} /> needs the graph as a string.
  • https://github.com/remcohaszing/remark-mermaidjs - A remark plugin to render mermaid diagrams using puppeteer
    2022-08-02 summary: not considering as puppeteer is a large dependency even if it works without much configuration needed

remark-mermaid

  • throwing errors: Expected usable value, not 'undefined' Looks like it's trying to parse wrong values.

Screen Shot 2022-07-26 at 6 00 07 PM

mdx-mermaid with remark-code-extra (UPDATE)

Using this remark plugin - https://github.com/s0/remark-code-extra - to replace pre tag elements created by rehype-prism-plus, I have managed to make mdx-mermaid work nicely with it. See screenshots below for result and modified code in contentlayer.config.js

Brief summary of modified code:

Transforming the nodes for <Pre> elements and removing the ones created by rehype-prism-plus ...

  • Added the remark plugin in contentlayer with following configuration within it:
    • create a new pre tag element with just the string value as child and a new className .code-mermaid
    • remove the previous pre tag element created by rehype-prism-plus
  • Modified the Pre.js component to check for the new className (code-mermaid) from props and if so, use Mermaid component ie. <Mermaid chart={children} />

Screen Shot 2022-08-02 at 6 07 07 PM

The remark-code-extra plugin in contentlayer.config.js looks like this:

Screen Shot 2022-08-02 at 6 18 49 PM

mdx-mermaid

  • adding mdx-mermaid as a remark plugin just outputs a string as seen below. Probably happening since import statements in md are not working/resolved.

Screen Shot 2022-07-27 at 5 18 24 AM

using mermaid component from mdx-mermaid in Pre.js component works after removing rehype-prism-plus plugin
Screen Shot 2022-07-27 at 5 24 20 AM

Why rehype-prism-plus conflicts:

rehype prism plus modifies all the code blocks including mermaid. for example below markdown

graph LR
     Start --> Stop

would generate individual span elements for each line

<span>graph LR</span>
<span>Start --> Stop</span>

Since mdx-mermaid component takes only a string <Mermaid chart={'graph LR ....'} />, we have to map each span element and join them as strings. This gets complex when there are elements within.

A better approach would be to somehow make rehype-prism-plus to discard modifying the language-mermaid code block.

remark-mermaidjs

https://github.com/remcohaszing/remark-mermaidjs

  • works and probably should go with this ...
  • needs some style fixes
    Screen Shot 2022-07-26 at 6 12 21 PM

Mermaidjs

https://mermaid-js.github.io/mermaid/#/

  • If using this option we have to:
    • configure Pre.js component used in MDXComponents to make this work
    • Also have to do more nested stuff since rehype-prism-plus converts code blocks to components
      if (/^language-mermaid/.test(children.props.className.toLocaleLowerCase())) {
        useEffect(() => mermaid.initialize({ startOnLoad: true }), [])
        return <div className="mermaid my-12">{children.props.children.map(el => el.props.children).join().replace(/,/g, "")} </div>
      }
    • Additional configuration for color code support required (not implemented)

Screen Shot 2022-07-26 at 6 21 59 PM

Feature Docs & Demo Page(s) v0.1

Create some demo pages that show off the features. This could be all in one or spread out over the features in docs.

Acceptance

  • All core features have a docs page e.g.
  • Basic markdown markup (can copy this page over from data-literate) βœ…2022-07-13 https://flowershow.app/docs/markdown
  • Wiki Links
  • Code Highlighting
  • Analytics configuration @olayway (tip look at config/siteConfig.js!) βœ…2022-07-19 https://flowershow.app/docs/analytics
  • User configuration (very simple - just mentioning existence of userConfig.js and (?) explaining how to edit it (?)) βœ…2022-07-20 #54
  • Navbar configuration @olayway i.e. edit navLinks list βœ…2022-07-20 #54
  • Layouts ?? i.e. overall page explaining layouts and then description of two options we currently have (maybe link to demos of them in docs e.g. /docs/layout-raw and docs/layout-docs βœ…2022-07-20 #54
  • grammar check πŸ˜›

Broken links to random pages

What happens

Sometimes internal links cause remark-wiki-link-plus errors (TypeError: Cannot read properties of undefined (reading 'startsWith')). I'm not sure how the pages that cause errors differ from the ones that don't though.

Steps to reproduce

  1. Create an internal link to docs/advanced/contentlayer, e.g. in docs/essentials/layoutes where I intended to add it.
  2. This results in the following error:
File updated: docs/essentials/layouts.md
event - compiled successfully in 143 ms (184 modules)
 > ../../templates/default/content/_mdx_bundler_entry_point-fa98af60-6507-4bb3-90cd-a464f130e0cd.mdx:0:0: error: [plugin: @mdx-js/esbuild] TypeError: Cannot read properties of undefined (reading 'startsWith')
    at _objectSpread.pageResolver (/home/ola/Projects/lifeitself/flowershow/templates/default/node_modules/remark-wiki-link-plus/dist/index.cjs.js:208:17)
    at Object.exitWikiLink (/home/ola/Projects/lifeitself/flowershow/templates/default/node_modules/remark-wiki-link-plus/dist/index.cjs.js:73:26)
    at compile (file:///home/ola/Projects/lifeitself/flowershow/templates/default/node_modules/mdast-util-from-markdown/lib/index.js:302:40)
    at fromMarkdown (file:///home/ola/Projects/lifeitself/flowershow/templates/default/node_modules/mdast-util-from-markdown/lib/index.js:120:29)
    at parser (file:///home/ola/Projects/lifeitself/flowershow/templates/default/node_modules/@mdx-js/esbuild/node_modules/remark-parse/lib/index.js:15:12)
    at Function.parse (file:///home/ola/Projects/lifeitself/flowershow/templates/default/node_modules/unified/lib/index.js:273:12)
    at executor (file:///home/ola/Projects/lifeitself/flowershow/templates/default/node_modules/unified/lib/index.js:393:31)
    at new Promise (<anonymous>)
    at Function.process (file:///home/ola/Projects/lifeitself/flowershow/templates/default/node_modules/unified/lib/index.js:380:14)
    at process (file:///home/ola/Projects/lifeitself/flowershow/templates/default/node_modules/@mdx-js/esbuild/node_modules/@mdx-js/mdx/lib/util/create-format-aware-processors.js:46:22)
    0 β”‚ # Layouts
      β•΅ ^

Error: Found 1 problems in 1 documents.

 └── Encountered unexpected errors while processing of 1 documents. This is possibly a bug in Contentlayer. Please open an issue.
     
     β€’ "docs/essentials/layouts.md": UnexpectedMDXError: Error: Build failed with 1 error:
     ../../templates/default/content/_mdx_bundler_entry_point-fa98af60-6507-4bb3-90cd-a464f130e0cd.mdx:0:0: error: [plugin: @mdx-js/esbuild] TypeError: Cannot read properties of undefined (reading 'startsWith')
         at _objectSpread.pageResolver (/home/ola/Projects/lifeitself/flowershow/templates/default/node_modules/remark-wiki-link-plus/dist/index.cjs.js:208:17)
         at Object.exitWikiLink (/home/ola/Projects/lifeitself/flowershow/templates/default/node_modules/remark-wiki-link-plus/dist/index.cjs.js:73:26)
         at compile (file:///home/ola/Projects/lifeitself/flowershow/templates/default/node_modules/mdast-util-from-markdown/lib/index.js:302:40)
         at fromMarkdown (file:///home/ola/Projects/lifeitself/flowershow/templates/default/node_modules/mdast-util-from-markdown/lib/index.js:120:29)
         at parser (file:///home/ola/Projects/lifeitself/flowershow/templates/default/node_modules/@mdx-js/esbuild/node_modules/remark-parse/lib/index.js:15:12)
         at Function.parse (file:///home/ola/Projects/lifeitself/flowershow/templates/default/node_modules/unified/lib/index.js:273:12)
         at executor (file:///home/ola/Projects/lifeitself/flowershow/templates/default/node_modules/unified/lib/index.js:393:31)
         at new Promise (<anonymous>)
         at Function.process (file:///home/ola/Projects/lifeitself/flowershow/templates/default/node_modules/unified/lib/index.js:380:14)
         at process (file:///home/ola/Projects/lifeitself/flowershow/templates/default/node_modules/@mdx-js/esbuild/node_modules/@mdx-js/mdx/lib/util/create-format-aware-processors.js:46:22)
     

SourceFetchDataError: {
  "_tag": "HandledFetchDataError"
}

Notes βœ… 2022-08-04 Bugfix

On investigation, the bug was related to filenames that were similar to the markdownFolder name, which in this case is 'content'. With further testing it was confirmed that this was the issue from remark-wiki-link-plus code that had a includes check.includes(markdown folder name). The code has been updated in remark-wiki-link-plus repo to resolve this issue.

Default theme v0.1

User story

As a user, I want to be able to start with a basic page layout to publish my content.

Acceptance

  • Front page basic layout
    • Nice hero
    • Rest of page can be markdown (just nicely styled) - cf syntax example after special links section is fine
  • Rest of pages - have standard markdown styling βœ…2022-07-16 looking nice. see screenshot
  • Navbar βœ…2022-07-14 it's working image
  • Footer βœ…2022-07-14 working now

image

image

Bonus

* [x] Work out how we refactor this out of the default template (or maybe leave as default template?) Let's treat this as our default template for now, as we don't have any other templates yet. In the future we cant create other ones and here is the issue for that. (For reference: this issue was previously named "Theme Flowershow Website").

Tasks

  • Choose a basic theme to use βœ…2022-07-08 can try-out tailwind theme e.g. "Syntax"
  • #55
  • Work on front page using MDX and basic copy we have
  • Navbar:
    • Refactor nav component as in theme template βœ… 2022-07-11
    • Add component MobileNavigation.js
  • Hero: as per 12/07/22 meeting: let's just use raw HTML instead of creating react components
    • Add components Hero.js Button.js βœ… 2022-07-11
    • Use Hero component in site/content/index.md
    • Image for hero
  • Have logo in navbar and footer etc βœ…2022-07-14 have a decent placeholder. More work in #33
  • Sections
  • Fonts Use default from template

Notes

  • While adding raw html in index.md for Hero, some styles were not being implemented. On further investigation it turns out that additional <p> tags are added to the html based on formatting. for eg in markdown ..
<div>
  <p className="...">
    // extra <p> tag added to below text on new line and styles from above not applied
    Some example text here
  </p>

  <p className="...">Some example text</p> // styles applied here and no extra <p> tag
</div>
  • How are we handling images for users ? Maybe makes more sense to symlink in public/images for now .. ?
  • Another way to add components in frontpage can be in the layouts section. For eg. index.md can have the docs layout but the Hero component will only be available for index page.
export default function Docs ({ children, frontMatter, components }) {
  return (
    <div className="prose max-w-full">
	{frontMatter._raw.sourceFilePath === "index.md" && <components.Hero />}
	<div className="max-w-4xl mx-auto py-8">
	  {children}
	</div>
    </div>
  )
}

This concept was taken from the tailwind docs theme template (which uses markdown) and we may be able to control rendering of components.

Link previews on hover

Distinguish external and internal link previews. For now focus on internal links.

Note we already implemented this in web3.lifeitself.org so i think a question of porting this over - see life-itself/web3#150 and PR life-itself/web3#162

Acceptance

  • When i hover over an (internal) link i get a preview of the contents (e.g. first X words) on that page
    • (also maybe the featured image if there is one?)

Example from https://web3.lifeitself.org/guide

image

Tasks

  • Research and estimate this βœ… 2022-12-13 Porting over from web3
  • Create docs with guide to toggle off βœ… 2022-12-14
  • Create the tooltip component βœ… 2022-12-14
    • modify to parse the content body using https://github.com/markedjs/marked ❌ not required using contentlayer instead
    • modify to use frontmatter image in preview if available
  • Add option to disable in config.js βœ… 2022-12-14

Use tailwind in (html/jsx) in markdown / mdx files

When creating pages for my site I want to (sometimes) use full html with tailwind so i can have fancy layouts or sections

Acceptance

  • can use html with tailwind in my content βœ…2022-07-06 you can do this by just adding content directory to tailwind which we can do by default now
  • documentation for this βœ…2022-07-07 in https://flowershow.app/docs/tailwind

Tasks

  • Change tailwind.config.js to track content/ folder - see below. βœ…2022-07-07 FIXED
  • Fix the constant hot reloading of pages βœ…2022-07-07 WONTFIX as not actually an issue we think - see comments

Notes

If we have a setup (as we have) like:

tailwind.config.js
content/ <= content is in here

should be as simple as tweaking tailwind.config.js as follows:

module.exports = {
   content: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}',
       'content/**/*.{md,mdx}'],  // <= added
}

This does work ... however it also seems to trigger nextjs into hot reloading the page all the time even with no changes. Need to debug and fix this - at least for development mode.

Excalidraw support i.e. docs on producing svg and conversion

Acceptance

  • Excalidraw images are published

BONUS (future for now probably)

  • Excalidraw images that are transcluded show up as they should even if using the default notation (i.e. not svg or png transclude)

Tasks

  • Displaying excalidraw images
    • Instructions to users on how to configure excalidraw to auto generate svg files (or png files?)
    • copying them to the public folder
    • Convert excalidraw embed codes to use the svg or png automatically? (just use the support of obsidian plugin which does this for you - don't get fancy)
  • Excalidraw excluded from contentlayer build (has .md files which aren't really md files) May not be needed as seems to be working ok without it. YAGNI
    • what happens if users are using a custom folder name? Let's default to Excalidraw at root of content folder

Table of content support in markdown

When writing my page I want to include a table of contents in the main body of the page (at a location I choose) so that people can see the overview of what is written

Can be quickly implemented with https://github.com/remarkjs/remark-toc (though note connection with slug generation for headings)

Acceptance

  • Can use some kind of indicator e.g. ## Table of Contents or {toc} or whatever to embed a table of contents in current page at that location
  • No control at user level over ToC depth (should be max possible and set generally)

Callouts support

We would follow Obsidian style as listed on here https://help.obsidian.md/How+to/Use+callouts

> [!INFO]
> Here's a callout block.
> It supports **markdown** and [[Internal link|wikilinks]].

Acceptance

repo: https://github.com/flowershow/remark-callouts
npm: https://www.npmjs.com/package/remark-callouts

  • Support blockquote obsidian style callouts
  • Support 13 type with appropriate styling in default theme
  • Supports nested blockquote callouts
  • Supports aliases for types
  • Defaults to note style callout for all other types eg. > [!xyz]
  • Supports dark and light mode styles

Screenshots

  • with callout

Screen Shot 2022-10-03 at 8 38 11 PM

  • without callout

Screen Shot 2022-10-03 at 8 39 25 PM

Tasks

  • Do analysis and estimate e.g. do we do a new remark plugin? (we could put in our existing plugin?) βœ… 2022-09-14 create new remark plugin @ repo: https://github.com/flowershow/remark-callouts
  • Add following features in plugin βœ… 2022-09-23
    • All admonitions that exist in obsidian including their aliases
    • Add custom titles (also support markdown)
    • Add nested callouts similar style in obsidian
    • Colors and Icons same as in obsidian
    • Add dark and light mode styles
  • Fix headings added due to rehype-auto-link-headings βœ… 2022-09-26
    • added classNames (blockquote-heading) so above package can emit

Notes

  • custom titles in callout headers can support markdown (as in obsidian) but not [[wiki-links]] (yet).

Monorepo setup and scaffolding

We will have various things in here probably so let's do the monorepo setup.

Acceptance

  • Monorepo setup with flowershow package in it at packages/flowershow 🚧2022-10-25 ❓ think we could rename CLI to be named flowershow consistent with npm naming βœ… 2022-10-31 olayway: from what I see in how nx handles creating new packages/apps by their generators in monorepos, how they do this in their docs but also how community does it, it's best to have all our packages published under flowershow organization, and publish them as scoped packages, i.e. they will be available under prefix @flowershow. Cool thing about it is that we can name our packages whatever we want and we don't have to worry about name clashes with some other public packages, so we can have our CLI package named just cli, and it will be published under @flowershow/cli
  • Moved templates/default into packages e.g. at packages/template (we can drop default for now!)
  • Linting and prettier in right place
  • tests in right place
  • changeset setup documented for monorepos (in e.g. flowershow.app/docs/developers

Tasks (old)

Preliminaries

  • Compare briefly monorepo tools e.g. nx, lerna, turborepo and make a choice
    • Brief summary of each
    • Choice βœ…2022-07-01 Let's go with nx
  • Create packages/ directory βœ…2022-08-?? done
  • Setup nx 🚧2022-10-25 ❓ is this relevant anymore?
  • Briefly document for other devs about anything they need to do in e.g. base README.md

Doing the work

  • Monorepo setup with flowershow package in it at packages/flowershow 🚧2022-10-25 ❓ think we could rename CLI to be named flowershow consistent with npm naming
  • Moved templates/default into packages e.g. at packages/template (we can drop default for now!)
  • Linting and prettier in right place
  • changeset setup documented for monorepos (in e.g. flowershow.app/docs/developers

[epic] Flowershow CLI v1

Creating a command line interface for flowershow.

Questions

  • Use typescript for this as a first tryout? βœ…2022-07-01 yes

Acceptance

  • Have a chosen a framework (shortlist: commander, oclif, arg - but this seems a bit too basic?)
  • npx flowershow or simple flowershow (if i have globally installed flowershow) command works and prints out basic help message (if no args etc)

Tasks

  • Create packages/flowershow
  • #134
  • CLI v0.2 add a preview / show command
  • CLI v0.3 add a build command

Notes

What do i want to do from command line or otherwise

Simplest thing: get into a directory and do flowershow dev/show and i get a running local preview

mkdir test
touch test/README.md
cd test
flowershow show

...

http://localhost:3000/ # browser automatically opened

Other functions

flowershow init
flowershow publish

[epic] Demo site

We'll want a demo site with sample content that is useful for both illustration and testing purposes.

Code highlighting

Nicely render code blocks in markdown

Suggest we use e.g. use https://github.com/timlrx/rehype-prism-plus

Acceptance

  • Code sections are nicely rendered (i.e. syntax highlight) βœ… using rehype-prism-plus
  • Have an example in demo page βœ… /demo/code-highlight
  • Bonus: copy and paste button seen on hover

Screen Shot 2022-07-12 at 6 25 51 AM

Tasks

  • Do we use prism or highlight.js. βœ…2022-06-29 Answer: prism i think (same speed, more plugins (?))
  • Add the plugin βœ… 2022-07-11
  • Add a section to demo to show it βœ… 2022-06-11
  • Copy/paste button βœ… 2022-07-11
    • Add component Pre.js to mdx
  • Styles used - prism vs code dark from https://github.com/PrismJS/prism-themes

SEO support

When creating a site I want to set description, image, title set on page (and have default values) so that have good SEO

There are really two parts to this:

  • Site-wide SEO: common and/or default SEO values for the whole site (and especially the front page)
  • Per-page SEO: SEO per page that overrides default SEO values. These would derive from frontmatter and/or be calculated e.g. title from markdown first heading etc (nb: any work to calculate title etc is out of scope for this issue - this issue can assume those values are available)

Priority right now is the first

We can follow the work we did in web3 for this e.g. life-itself/web3#114

Acceptance

Proposed Default Next SEO (note other SEO values would get set from other config values e.g. title and description)

nextSeo: {
    openGraph: {
      images: [
        {
          url: "https://web3.lifeitself.us/img/home-page-screenshot-social-preview.png",
          alt: "",
          width: 1200,
          height: 627,
          type: "image/jpg",
        },
      ],
    },
    twitter: {
      handle: "@forlifeitself",
      site: "web3.lifeitself.us",
      cardType: "summary_large_image",
    },
  },

Tasks

  • Create docs
  • ...

[inbox][epic] Docs and Site

When coming to Flowershow for the first time i want to read the docs to try it out.

This is not a real issue but a catch-all for planning and tracking docs work.

See the 4-fold approach to https://documentation.divio.com

image

Misc - Jan 2023

Front page

  • clear and up-to-date list of features
  • better call to action
  • clear landing page for user types e.g. digital garden, use for docs, use for ordinary website

Docs

  • up-to-date docs
  • re-org docs
  • site-wide table of contents for /docs paths
  • better cloud publishing marketing βœ…2023-12-19 done as of nov 2023

Tutorials

How to use Flowershow for X (or how we used flowershow for X)

  • Self-publishing in general #165
    • Publish single and obisidan v1 #131
    • Self-publish tutorial v2 #257
  • Customize front page
    • Customize hero section #133
    • Customize whole page
  • Theme your flowershow site
    • Fonts and colors #292
    • Change navbar
    • Change footer
  • Tutorial: Add a blog to Flowershow (or Create a Blog with Flowershow)
  • Custom page types and layout e.g. organization profile pages on ecosystem site
  • NextJS template #396

Howtos

  • Setup SEO for a page or the whole site
  • Access the config and change it
  • Markdown extension addition i.e. add your own remark plugin to do some kind of processing #advanced #customization

Reference

  • Working with contentlayer and content structuring #advanced #customization

Competitive analysis

Check what cool features other products like Obsidian Publish or Quartz have, that we would like to provide as well.

Also check out other broader alternatives beyond obsidian e.g.

  • Cloud platforms e.g. gitbook, readme.io
  • Tooling especially for docs e.g. mkdocs-material, docosaurus, vitepress (vuepress 3)
  • static site generators especially low maintenance ones e.g. 11ty, zola

Tasks

  • Database of examples

[epic] Trial flowershow with some sites

Trial product e.g. on flowershow itself or building Life Itself new community site. Possible candidates

  • flowershow site itself 🚧2022-07-06 50% - already in use but more needed e.g. for landing page
  • ecosystem site 🚧2022-07-06 60% 2022-07-08 90% migration done and writing up learnings
  • web3 (refactor) ?? βœ…2023-03-27 ❌ not needed for now
  • Life Itself community site βœ…2023-01-05 completed in jan 2023 https://lifeitself.org/

Acceptance

  • flowershow.app running off this βœ…2022-08-17 this is now fully working and we have split out components from main app into site
  • ecosystem site running off this 🚧2022-08-17 running but we need to update as had custom stuff
  • #104
  • learnings and challenges written up

Tasks

  • flowershow site running off this
    • learnings and challenges
  • ecosystem site running off this life-itself/secondrenaissance#81
    • Learnings from Flowershow v0.1 trial with ecosystem @khalilcodes
      • Diff all changed files and note changes with any insights
      • Summarize questions arising below
    • Immediate changes to upstream
      • Move allDocuments change upstream to flowershow
      • Move upstream change to unstyled.js (?)

Issues from ecosystem upgrade

  • How would we handle changes to mdx.js
  • How do i know which components come from flowershow and can be upgraded vs are custom to the user Refactor flowershow so all flowershow components are in a subfolder called flowershow or similar. Or have user components in a specific folder distinct from components
  • When trying to reuse index.js encountered: βœ…2022-08-23 the resolution for now is to use tailwind and JS components in your index.md
    • You cannot define a route with the same specificity as a optional catch-all route ("/" and "/[[...slug]]")
    • Two direction to go in: a) try using mdx and moving stuff into mdx b) use index.js which means changing [[...slug]] to [..slug] βœ…2022-08-23 move stuff into mdx
      • First option requires tailwind parsing of markdown directory βœ…2022-08-23 we've done this
      • Also requires loading data in some way or other βœ…2022-08-23 see #88 i think for resolution on this
  • General question re flowershow: theming seems so essential and is quite limited without access to Layout + tailwind stuff
    • Once you give that why not whole of nextjs
    • Other aspect of nextjs is basically data passing

Notes from Ecosystem upgrade

Changes

This shows changes to files in the app in ecosystem vs original flowershow. Additions aren't a problem at all. It's changes that are a problem.

components
  Hero          # ADD
  Link
  Search
  TernaryPlot
  CircularVis
  
  MDX.js            # CHANGED

layouts
  unstyled.js      # ~~CHANGED~~ (MINOR and MERGED UPSTREAM)
  profile.js       	  # ADD

pages
  _app.js          # CHANGED
  [[...slug]].js   # CHANGED

package.json  # CHANGED all the d3 stuff (git diff would be useful here)

unstyled.js

git diff 1766db630dcac5eaf81e00d95bdbe7a3a3647447 5cd6035c8963ea7819272e8d38235adacc49dc5f layouts/unstyled.js

 export default function UnstyledLayout ({ children, frontMatter }) {
-    return children
+    return <div className="prose mx-auto max-w-full">{children}</div>
 }

MDX.js

(UPDATE)
git diff 1766db630dcac5eaf81e00d95bdbe7a3a3647447 d9154b0e5438a18c1b5596ce0f4e22c389121379 components/MDX.js

+import { Fragment } from 'react'
+import dynamic from 'next/dynamic'
 import Head from 'next/head'
+import Link from 'next/link'
+import Hero from './Hero'
+import Search from './Search'
+
+const TernaryPlot = dynamic(() => import('./TernaryPlot'))
+const CircularVis = dynamic(() => import('./CircularVis'))

 const components = {
   Head,
+  Hero,
+  Link,
+  Search,
+  svg: props => <Fragment {...props} />,
+  TernaryPlot,
+  CircularVis,

git diff 1766db630dcac5eaf81e00d95bdbe7a3a3647447 4b40577c51f407e5e278140163339fc3b722ee0b components/MDX.js

+import { Fragment } from 'react'
 import Head from 'next/head'
+import Link from 'next/link'
+import Hero from './Hero'
+import TernaryPlot from './TernaryPlot'
+import CircularVis from './CircularVis'
+import Search from './Search'
 
 const components = {
   Head,
+  Hero,
+  Link,
+  Search,
+  svg: props => <Fragment {...props} />,
+  TernaryPlot,
+  CircularVis,
   wrapper: ({ layout, ...rest }) => {
     const Layout = require(`../layouts/${layout}`).default
     return <Layout {...rest} />

[[...slug]].js

  • allDocuments changes is an artefact and should move upstream to flowershow
  • allProfiles filtering should be in lib/db.js

(UPDATE)

lib/db.js

import { allProfiles } from 'contentlayer/generated';

export default async function getProfiles() {
  const result = await allProfiles.filter(profile => 
    !(profile.curation_status.includes('N') || profile.curation_status.includes('?'))
  )
  return result
} 

git diff 1766db630dcac5eaf81e00d95bdbe7a3a3647447 44acfcfa9d8e9eae3f618cb6568e348c77b1d12e pages/\[\[...slug\]\].js

-import { allPages } from "contentlayer/generated";
+import { allDocuments } from "contentlayer/generated";
 import { useMDXComponent } from "next-contentlayer/hooks";
 import MdxPage from "../components/MDX";
+import getProfiles from "../lib/db";

-export default function Page({ body, ...rest }) {
-  const Component = useMDXComponent(body.code);
+export default function Page({ page: { body, ...rest }, orgs }) {
+  const Component = useMDXComponent(body.code, { orgs });
+
   const children = {
     Component,
     frontMatter: {
@@ -16,13 +18,17 @@ export default function Page({ body, ...rest }) {
 export async function getStaticProps({ params }) {
   // params.slug is undefined for root index page
   const urlPath = params.slug ? params.slug.join("/") : '';
-  const page = allPages.find((p) => p.url === urlPath);
-  return { props: page };
+  const page = allDocuments.find((p) => p.url_path === urlPath);
+
+  //  load orgs only for pages that require them (eg. pages containing a vis).
+  const orgs = /{orgs}/.test(page.body.code) ? await getProfiles() : null
+
+  return { props: { page, orgs } };
 }

 export async function getStaticPaths() {
-  const paths = allPages.map((page) => {
-    const parts = page.url.split("/");
+  const paths = allDocuments.map((page) => {
+    const parts = page.url_path.split("/");
     return { params: { slug: parts } };
   });

git diff 1766db630dcac5eaf81e00d95bdbe7a3a3647447 ca1ce9a76e1840bd53492dcb3885880effd5c5b5 pages/\[\[...slug\]\].js

-import { allPages } from "contentlayer/generated";
+import { allDocuments, allProfiles } from "contentlayer/generated";
 import { useMDXComponent } from "next-contentlayer/hooks";
 import MdxPage from "../components/MDX";
 
 export default function Page({ body, ...rest }) {
-  const Component = useMDXComponent(body.code);
+  const filteredProfiles = allProfiles.filter(profile => 
+    !(profile.curation_status.includes('N') || profile.curation_status.includes('?'))
+  )
+
+  const Component = useMDXComponent(body.code, {
+    orgs: filteredProfiles
+  });
+  
   const children = {
     Component,
     frontMatter: {
@@ -16,13 +28,13 @@ export default function Page({ body, ...rest }) {
 export async function getStaticProps({ params }) {
   // params.slug is undefined for root index page
   const urlPath = params.slug ? params.slug.join("/") : '';
-  const page = allPages.find((p) => p.url === urlPath);
+  const page = allDocuments.find((p) => p.url_path === urlPath);
   return { props: page };
 }
 
 export async function getStaticPaths() {
-  const paths = allPages.map((page) => {
-    const parts = page.url.split("/");
+  const paths = allDocuments.map((page) => {
+    const parts = page.url_path.split("/");
     return { params: { slug: parts } };
   });

package.json

git diff 1766db630dcac5eaf81e00d95bdbe7a3a3647447 d0d578f9a71c45dd8146183d0c79771ca3982347 package.json

     "@silvenon/remark-smartypants": "^1.0.0",
     "@tailwindcss/typography": "^0.5.2",
     "contentlayer": "^0.2.5",
+    "d3": "^7.6.1",
+    "d3-ternary": "^2.0.14",
+    "fuse.js": "^6.6.2",
     "gray-matter": "^4.0.3",
+    "itemsjs": "^2.1.15",
     "next": "^12.1.0",
     "next-contentlayer": "^0.2.5",
     "next-seo": "^4.28.1",
@@ -25,6 +29,7 @@
   },
   "devDependencies": {
     "@playwright/test": "^1.22.2",
+    "@tailwindcss/forms": "^0.5.2",
     "autoprefixer": "^10.4.4",
     "postcss": "^8.4.12",
     "tailwindcss": "^3.0.23"

Notes from creating Flowershow website using Flowershow template

MDX syntax support

MDX syntax fully works and is documented on this page - https://flowershow.app/docs/mdx.

Most important syntax elements that work:

  • JSX,
  • ESM import and export statements which allow for importing as well as locally defining components/data,
  • evaluating JS expressions wrapped in {}.

Separation of template components and user defined components

You can have custom components outside of the Flowershow template's /components dir and still import them in MDX files.

In order to have less confusing import paths atm we're symlinking the folder with custom components (in our case /site/components) to flowershow/templates/default/components. See issue #88 to learn more.

Tailwind

You can use Tailwind to style JSX components in your MDX files. This is documented here: https://flowershow.app/docs/tailwind

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.