github.com/Jeffail/benthos/v3@v3.65.0/website/src/plugins/cookbooks/index.js (about) 1 /** 2 * Copyright (c) 2017-present, Facebook, Inc. 3 * 4 * This source code is licensed under the MIT license found in the 5 * LICENSE file in the root directory of this source tree. 6 */ 7 8 const path = require('path'); 9 const {normalizeUrl, docuHash, aliasedSitePath} = require('@docusaurus/utils'); 10 11 const {generateCookbookPosts} = require('./cookbookUtils'); 12 13 const DEFAULT_OPTIONS = { 14 path: 'cookbooks', // Path to data on filesystem, relative to site dir. 15 routeBasePath: 'cookbooks', // URL Route. 16 include: ['*.md', '*.mdx'], // Extensions to include. 17 guideListComponent: '@theme/CookbookListPage', 18 guidePostComponent: '@theme/CookbookPage', 19 remarkPlugins: [], 20 rehypePlugins: [], 21 truncateMarker: /<!--\s*(truncate)\s*-->/, // string or regex 22 }; 23 24 const { 25 STATIC_DIR_NAME, 26 DEFAULT_PLUGIN_ID, 27 } = require('@docusaurus/utils'); 28 29 module.exports = pluginContentCookbook; 30 31 function pluginContentCookbook(context, opts) { 32 const options = {...DEFAULT_OPTIONS, ...opts}; 33 const {siteDir, generatedFilesDir} = context; 34 const contentPath = path.resolve(siteDir, options.path); 35 36 const pluginDataDirRoot = path.join( 37 generatedFilesDir, 38 'cookbooks', 39 ); 40 const dataDir = path.join(pluginDataDirRoot, options.id || DEFAULT_PLUGIN_ID); 41 42 return { 43 name: 'cookbooks', 44 45 getPathsToWatch() { 46 const {include = []} = options; 47 const globPattern = include.map(pattern => `${contentPath}/${pattern}`); 48 return [...globPattern]; 49 }, 50 51 // Fetches guide contents and returns metadata for the necessary routes. 52 async loadContent() { 53 const guidePosts = await generateCookbookPosts(contentPath, context, options); 54 if (!guidePosts.length) { 55 return null; 56 } 57 58 return { 59 guidePosts, 60 }; 61 }, 62 63 async contentLoaded({content, actions}) { 64 if (!content) { 65 return; 66 } 67 68 const { 69 guideListComponent, 70 guidePostComponent, 71 } = options; 72 73 const aliasedSource = (source) => 74 `~cookbooks/${path.relative(pluginDataDirRoot, source)}`; 75 const {addRoute, createData} = actions; 76 const { 77 guidePosts, 78 } = content; 79 80 // Create routes for guide entries. 81 await Promise.all( 82 guidePosts.map(async guidePost => { 83 const {metadata} = guidePost; 84 await createData( 85 // Note that this created data path must be in sync with metadataPath provided to mdx-loader 86 `${docuHash(metadata.source)}.json`, 87 JSON.stringify(metadata, null, 2), 88 ); 89 90 addRoute({ 91 path: metadata.permalink, 92 component: guidePostComponent, 93 exact: true, 94 modules: { 95 content: metadata.source, 96 }, 97 }); 98 }), 99 ); 100 101 const {routeBasePath} = options; 102 const { 103 siteConfig: {baseUrl = ''}, 104 } = context; 105 const basePageUrl = normalizeUrl([baseUrl, routeBasePath]); 106 107 const listPageMetadataPath = await createData( 108 `${docuHash(`${basePageUrl}`)}.json`, 109 JSON.stringify({}, null, 2), 110 ); 111 112 let basePageItems = guidePosts.map(guidePost => { 113 const {metadata} = guidePost; 114 // To tell routes.js this is an import and not a nested object to recurse. 115 return { 116 content: { 117 __import: true, 118 path: metadata.source, 119 query: { 120 truncated: true, 121 }, 122 }, 123 }; 124 }); 125 126 addRoute({ 127 path: basePageUrl, 128 component: guideListComponent, 129 exact: true, 130 modules: { 131 items: basePageItems, 132 metadata: aliasedSource(listPageMetadataPath), 133 }, 134 }); 135 }, 136 137 configureWebpack( 138 _config, 139 isServer, 140 {getJSLoader}, 141 ) { 142 const {rehypePlugins, remarkPlugins, truncateMarker} = options; 143 return { 144 resolve: { 145 alias: { 146 '~cookbooks': pluginDataDirRoot, 147 }, 148 }, 149 module: { 150 rules: [ 151 { 152 test: /(\.mdx?)$/, 153 include: [contentPath], 154 use: [ 155 getJSLoader({isServer}), 156 { 157 loader: require.resolve('@docusaurus/mdx-loader'), 158 options: { 159 remarkPlugins, 160 rehypePlugins, 161 staticDir: path.join(siteDir, STATIC_DIR_NAME), 162 // Note that metadataPath must be the same/ in-sync as the path from createData for each MDX 163 metadataPath: (mdxPath) => { 164 const aliasedPath = aliasedSitePath(mdxPath, siteDir); 165 return path.join( 166 dataDir, 167 `${docuHash(aliasedPath)}.json`, 168 ); 169 }, 170 }, 171 }, 172 { 173 loader: path.resolve(__dirname, './markdownLoader.js'), 174 options: { 175 truncateMarker, 176 }, 177 }, 178 ].filter(Boolean), 179 }, 180 ], 181 }, 182 }; 183 }, 184 }; 185 }