├── .babelrc ├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── components ├── BackToTop.jsx ├── BlogListIndex.tsx ├── Button.tsx ├── CoolHead.jsx ├── DocComponents │ ├── Asides.tsx │ ├── Breadcrumbs.tsx │ ├── Card.tsx │ ├── Cards │ │ ├── Danger.tsx │ │ ├── Example.tsx │ │ ├── Note.tsx │ │ ├── Tips.tsx │ │ ├── To.tsx │ │ └── Warn.tsx │ ├── Collapse.jsx │ ├── HeadSidebar.tsx │ ├── Headings.tsx │ ├── Icon │ │ ├── Exclamation.tsx │ │ └── index.tsx │ ├── PostIndexBar.tsx │ ├── PostIndexTree.tsx │ ├── PostList.tsx │ ├── PostSidebar.tsx │ ├── PostTree.tsx │ ├── SearchIn.jsx │ ├── Sidebar.tsx │ ├── Tree.tsx │ ├── WarningBox.jsx │ └── index.ts ├── Feter.jsx ├── Footer.jsx ├── Header.tsx ├── Hero.jsx ├── NavBar.jsx ├── Powerby.tsx ├── RightAuthor.jsx ├── ThemeChange.tsx ├── WebsiteCard.tsx ├── icons │ ├── IconJujin.tsx │ └── index.ts └── styles.module.css ├── content ├── docs │ ├── 000-fastgo │ │ ├── 000-preparation.zh.mdx │ │ ├── 001-content.zh.mdx │ │ ├── 002-sometry.zh.mdx │ │ ├── index.mdx │ │ └── index.zh.mdx │ ├── 001-docandblog │ │ ├── 000-docsstruct.mdx │ │ ├── 001-poststruct.mdx │ │ └── index.zh.mdx │ ├── 002-markdowntext │ │ ├── 001-headings.mdx │ │ ├── 002-boldthing.mdx │ │ ├── 003-codinglang.mdx │ │ ├── 004-notice.mdx │ │ ├── 005-linkings.mdx │ │ ├── 006-pictures.mdx │ │ └── index.mdx │ ├── 003-api │ │ ├── 000-themes.mdx │ │ ├── 001-navsetting.mdx │ │ └── index.mdx │ ├── 004-build │ │ ├── 000-saveit.mdx │ │ ├── 001-netlify.mdx │ │ ├── 002-vercel.mdx │ │ └── index.mdx │ ├── 005-improve │ │ ├── 000-newpages.mdx │ │ ├── 001-csschange.mdx │ │ └── index.mdx │ ├── index.mdx │ └── index.zh.mdx └── posts │ ├── .gitkeep │ ├── 2022-08-31-blogone │ └── index.mdx │ ├── 2022-08-31-blogtwo │ └── index.mdx │ ├── 2022-09-01-blogthree │ └── index.mdx │ ├── index.mdx │ └── index.zh.mdx ├── contentlayer.config.ts ├── daymd.config.js ├── navData ├── friend.ts └── website.ts ├── next-env.d.ts ├── next-i18next.config.js ├── next.config.js ├── package-lock.json ├── package.json ├── pages ├── _app.tsx ├── docs │ └── [[...slug]].tsx ├── index.tsx ├── posts │ └── [[...slug]].tsx └── website │ └── index.tsx ├── postcss.config.js ├── public ├── images │ ├── banner1.svg │ ├── banner2.svg │ ├── banner3.svg │ ├── favicon.png │ └── scrooltop.svg └── locales │ ├── en │ ├── common.json │ └── docs.json │ └── zh │ ├── common.json │ └── docs.json ├── src ├── configs │ └── constants.ts ├── contentlayer │ ├── plugins │ │ └── index.ts │ ├── types │ │ ├── doc.ts │ │ └── post.ts │ └── utils │ │ └── index.ts └── themes │ ├── brackets-light-pro.json │ └── moonlight-ii.json ├── styles ├── app.css ├── globals.css ├── markdown.css ├── styles.module.css └── website.module.css ├── tailwind.config.js ├── tsconfig.json ├── typings └── index.ts └── utils ├── generate-breadcrumbs.ts ├── generate-docs-tree.ts ├── generate-paths.ts ├── generate-posts-tree.ts ├── key-match.ts └── title-to-slug.ts /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["next/babel"] 3 | } 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .next 4 | .contentlayer 5 | yarn.lock 6 | .DS_Store 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [2022] [inannan423] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 组合式站点生成器 2 | 3 | 特性: 4 | 5 | - 零基础上手 6 | - 28 种主题 7 | - 在浏览器完成全部工作,不需要本地环境 8 | - 灵活开放 9 | 10 | [详细文档](https://daymd.netlify.app) 11 | 12 | ## 预览 13 | 14 | ![image](https://github.com/inannan423/Daymd/assets/83146544/89b1563b-e9b1-4b22-91c2-5813f080b771) 15 | ![image](https://github.com/inannan423/Daymd/assets/83146544/b4464713-a030-4f9d-b97c-893f2ab4c36a) 16 | ![image](https://github.com/inannan423/Daymd/assets/83146544/0a1e08c7-244a-41cf-9d4f-2f1fcbe1c1da) 17 | 18 | 19 | ## 本地运行 20 | 21 | 克隆源代码。 22 | 23 | ```bash 24 | npm install 25 | ``` 26 | 27 | 运行。 28 | 29 | ```bash 30 | npm run dev 31 | ``` 32 | 33 | 打包 34 | 35 | ```bash 36 | npm run build 37 | ``` 38 | -------------------------------------------------------------------------------- /components/BackToTop.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | 3 | class ScrollToTop extends Component { 4 | constructor(props) { 5 | super(props); 6 | 7 | //show为true时回到顶部按钮显示,false时隐藏 8 | this.state = { 9 | show: false, 10 | }; 11 | //将函数里的this指向绑定到当前组件,也就是组件ScrollToTop 12 | this.changeScrollTopShow = this.changeScrollTopShow.bind(this); 13 | this.scrollToTop = this.scrollToTop.bind(this); 14 | } 15 | //挂载事件监听 16 | componentDidMount() { 17 | window.addEventListener("scroll", this.changeScrollTopShow); 18 | } 19 | //卸载事件监听 20 | componentWillUnmount() { 21 | window.removeEventListener("scroll", this.changeScrollTopShow); 22 | } 23 | render() { 24 | const { show } = this.state; 25 | return ( 26 | //ScrollToTopWrapper是一个由styled-components定义的样式组件,其本质 27 | //是一个div标签 28 | 38 | ); 39 | } 40 | //控制show的状态从而控制回到顶部按钮的显示和隐藏 41 | changeScrollTopShow() { 42 | if (window.pageYOffset < 400) { 43 | this.setState({ 44 | show: false, 45 | }); 46 | } else { 47 | this.setState({ 48 | show: true, 49 | }); 50 | } 51 | } 52 | //添加动画效果 53 | scrollToTop() { 54 | const scrollToTop = window.setInterval(() => { 55 | let pos = window.pageYOffset; 56 | if (pos > 0) { 57 | window.scrollTo(0, pos - 20); 58 | } else { 59 | window.clearInterval(scrollToTop); 60 | } 61 | }, 1); 62 | } 63 | } 64 | 65 | //导出组件 66 | export default ScrollToTop; 67 | -------------------------------------------------------------------------------- /components/BlogListIndex.tsx: -------------------------------------------------------------------------------- 1 | import { RightAuthor } from "./RightAuthor"; 2 | import { Tree } from "./DocComponents/Tree"; 3 | import { PostSidebar } from "./DocComponents/PostSidebar"; 4 | import { generatePaths } from "../utils/generate-paths"; 5 | import { PostHeading, PostMeta } from "../src/contentlayer/types/post"; 6 | import { allPosts, Post } from "../.contentlayer/generated/index"; 7 | import { generatePostsTree, TNode } from "../utils/generate-posts-tree"; 8 | import { titleToSlug } from "../utils/title-to-slug"; 9 | import Parallax from "react-rellax"; 10 | import { Locale } from "../typings"; 11 | import configs from "../daymd.config"; 12 | import type { 13 | GetStaticPaths, 14 | GetStaticProps, 15 | InferGetStaticPropsType, 16 | } from "next"; 17 | import { PostIndexBar } from "./DocComponents/PostIndexBar"; 18 | export const getStaticPaths: GetStaticPaths = async () => ({ 19 | paths: [ 20 | ...generatePaths(allPosts, Locale.EN), 21 | ...generatePaths(allPosts, Locale.ZH), 22 | ], 23 | fallback: false, 24 | }); 25 | 26 | export const getStaticProps: GetStaticProps< 27 | { 28 | doc: Post; 29 | tree: Array; 30 | crumbs: Array<{ title: string; route: string }>; 31 | }, 32 | { slug?: string[] } 33 | > = async (context) => { 34 | const [params, locale] = [context.params, context.locale]; 35 | 36 | const pageRoute = params?.slug?.join("/") ?? ""; 37 | 38 | const map: { [key: string]: number } = {}; 39 | const localeDocs = allPosts 40 | .sort((a) => (a.locale === locale ? -1 : 1)) 41 | .filter((d) => (map[d.route] ? 0 : (map[d.route] = 1))); 42 | 43 | const doc = localeDocs.find((d) => d.route === pageRoute)!; 44 | 45 | const crumb = { 46 | title: "", 47 | route: "", 48 | }; 49 | 50 | const crumbs = [ 51 | { 52 | route: "/posts", 53 | title: configs.postPageTitle, 54 | }, 55 | ...doc.meta.map(({ slug }: PostMeta) => { 56 | crumb.route += crumb.route === "" ? slug : "/" + slug; 57 | const title = localeDocs.find((d) => d.route === crumb.route)?.title; 58 | // Path1 = crumb.route; 59 | return { route: "/posts/" + crumb.route, title }; 60 | }), 61 | ]; 62 | 63 | const tree = generatePostsTree(localeDocs); 64 | 65 | return { 66 | props: { 67 | doc, 68 | tree, 69 | crumbs, 70 | }, 71 | }; 72 | }; 73 | 74 | function BlogBack() { 75 | return ( 76 |
84 | 85 |
86 | {configs.heroText} 87 |
88 |
{" "} 89 |
90 | ); 91 | } 92 | 93 | function BlogBackMax() { 94 | return ( 95 |
103 | {/* 添加透明遮罩 */} 104 |
105 | {/*
*/} 106 |
107 | ); 108 | } 109 | 110 | export default function BlogListItem({ 111 | doc, 112 | tree, 113 | crumbs, 114 | }: InferGetStaticPropsType) { 115 | return ( 116 |
117 |
121 |
122 |

{doc.title}

123 |

{doc.excerpt}

124 |
125 |
126 |
127 | ); 128 | } 129 | 130 | function isBlogMax() { 131 | if (configs.theme2Setting.backSize === 1) { 132 | return ; 133 | } else if (configs.theme2Setting.backSize === 2) { 134 | return ; 135 | } else if (configs.theme2Setting.backSize === 3) { 136 | return ( 137 | <> 138 | 139 | 140 | 141 | ); 142 | } 143 | } 144 | 145 | export const BlogListIndex: React.FC<{ tree: TNode[] }> = ({ tree }) => ( 146 |
147 | {isBlogMax()} 148 |
152 |
153 |
154 | 155 |
156 |
157 | 158 |
159 |
160 |
161 | ); 162 | -------------------------------------------------------------------------------- /components/Button.tsx: -------------------------------------------------------------------------------- 1 | import { FC } from 'react' 2 | import React from 'react' 3 | 4 | export const Button: FC<{ title: string }> = ({ title }) => ( 5 |
alert('Hi')} 8 | > 9 | {title} 10 |
11 | ) 12 | -------------------------------------------------------------------------------- /components/CoolHead.jsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link"; 2 | import { useEffect } from "react"; 3 | import Parallax from "react-rellax"; 4 | import configs from "../daymd.config"; 5 | import { Feter } from "./Feter"; 6 | import { Poweredby } from "./Powerby"; 7 | const PageData = { 8 | headTitle: "Get it all done", 9 | headTitle1: "with detailed APIs", 10 | headTitleChinese: "您只需负责填空,剩下的全交给我", 11 | }; 12 | 13 | function Zhanwei() { 14 | return
; 15 | } 16 | 17 | function Title() { 18 | return ( 19 |
20 | 21 | {PageData.headTitle}
22 | {PageData.headTitle1}
23 |

{PageData.headTitleChinese}

24 |
25 |
26 |
27 | {/*
28 |
*/} 29 |
30 |
31 | ); 32 | } 33 | 34 | function BigMax() { 35 | return ( 36 |
37 | 38 |
39 | ); 40 | } 41 | 42 | function Coding() { 43 | return ( 44 |
45 |
46 | 47 | 核心理念 48 | 49 |
50 |
51 |
52 |
 53 |             title: "Daymd.", 
 54 |           
55 |
 56 |             heroMode: 0, 
 57 |           
58 |
 59 |             isNavLogo: 1, 
 60 |           
61 |
 62 |             heroButton: "Get Start", 
 63 |           
64 |
 65 |             heroButtonLink: "/posts/change-me", 
 66 |           
67 |
 68 |             favicon: "https://jetzihan-img/daymd_logo1.svg", 
 69 |           
70 |
71 |
72 |
73 |

“设置式” 构建

74 |

75 | 就像手机设置一样,对不同的选项进行设置,就能达到你想要的结果。 76 |

77 |
78 | 79 | 80 | 81 |
82 |
83 |
84 |
85 |
86 | ); 87 | } 88 | 89 | function StartButton() { 90 | return ( 91 | 92 |
93 | 99 |
100 | 101 | ); 102 | } 103 | 104 | function Codebox() { 105 | return ( 106 |
107 |
108 | 109 | 在 daymd.config.js 中搞定一切 110 | 111 |
112 |
113 | 127 |
128 |
129 | ); 130 | } 131 | 132 | export function CoolHead() { 133 | return ( 134 |
135 | 136 | {/* */} 137 | 138 | {/* </Parallax> */} 139 | <Parallax speed={-1}> 140 | <BigMax /> 141 | </Parallax> 142 | 143 | <Feter /> 144 | <Coding /> 145 | <Codebox /> 146 | <StartButton /> 147 | <div className="w-screen h-84 p-5 justify-center items-center"> 148 | <Poweredby /> 149 | </div> 150 | </div> 151 | ); 152 | } 153 | -------------------------------------------------------------------------------- /components/DocComponents/Asides.tsx: -------------------------------------------------------------------------------- 1 | import type React from "react"; 2 | import { createContext, useEffect, useState } from "react"; 3 | import cn from "classnames"; 4 | import { useTranslation } from "next-i18next"; 5 | 6 | // import { Sandpack, SandpackToggle } from "../sandpack"; 7 | import { PostHeading } from "../../src/contentlayer/types/post"; 8 | import { motion } from "framer-motion"; 9 | import { titleToSlug } from "../../utils/title-to-slug"; 10 | import configs from "../../daymd.config"; 11 | export const AsideContext = createContext<{ showSide: boolean }>({ 12 | showSide: false, 13 | }); 14 | 15 | export const Aside: React.FC<{ 16 | children: (showSide: boolean) => React.ReactNode; 17 | }> = ({ children }) => { 18 | const [showSide, setshowSide] = useState(false); 19 | 20 | return ( 21 | <AsideContext.Provider value={{ showSide }}> 22 | {children(showSide)} 23 | {/* <SandpackToggle toggle={() => setshowSide(!showSide)} /> */} 24 | </AsideContext.Provider> 25 | ); 26 | }; 27 | 28 | type AsidesProps<T> = { 29 | visible: boolean; 30 | } & T; 31 | 32 | export const HeadingsAside: React.FC< 33 | AsidesProps<{ 34 | headings: PostHeading[]; 35 | active: number; 36 | }> 37 | > = ({ headings, active }) => { 38 | const { t } = useTranslation("docs"); 39 | const [current, setCurrent] = useState(active); 40 | 41 | useEffect(() => setCurrent(active), [active]); 42 | 43 | return ( 44 | <div 45 | style={{ position: "sticky", top: "0" }} 46 | className={cn( 47 | " h-min mt-10 space-y-4 px-6 py-4 w-64 border-l-2 border-opacity-25 border-blue-100" 48 | )} 49 | > 50 | <h3 className={cn(" uppercase font-bold text-content")}> 51 | {configs.rightContentText} 52 | </h3> 53 | <nav className={cn("grow h-screen overflow-y-scroll overscroll-auto")}> 54 | <ul className={cn("space-y-1.5 ")}> 55 | {headings.length && 56 | [...headings] 57 | .filter((h) => h.level > 1) 58 | .map((h, i) => ( 59 | <li 60 | role="link" 61 | key={i} 62 | className={cn( 63 | "relative flex", 64 | ["", "", "", "pl-2", "pl-4", "pl-6", "pl-8"].map((pl, l) => 65 | h.level === l ? pl : "" 66 | ) 67 | )} 68 | > 69 | <a 70 | href={`#${titleToSlug(h.title)}`} 71 | className={cn( 72 | "px-3 py-1 w-full transition-all ease-in-out duration-600 rounded-md text-sm", 73 | i === current 74 | ? "text-theme-500 text-primary " 75 | : "hover:bg-primary/40 ", 76 | h.level > 2 && "font-light" 77 | )} 78 | onClick={() => setCurrent(i)} 79 | > 80 | {h.title} 81 | </a> 82 | </li> 83 | ))} 84 | </ul> 85 | </nav> 86 | </div> 87 | ); 88 | }; 89 | -------------------------------------------------------------------------------- /components/DocComponents/Breadcrumbs.tsx: -------------------------------------------------------------------------------- 1 | import type React from "react"; 2 | import cn from "classnames"; 3 | import Link from "next/link"; 4 | import { FaChevronRight } from "react-icons/fa"; 5 | 6 | interface BreadcrumbsProps { 7 | crumbs: Array<{ title: string; route: string }>; 8 | } 9 | 10 | export const Breadcrumbs: React.FC<BreadcrumbsProps> = ({ crumbs }) => { 11 | return ( 12 | <ul className="text-base flex h-10"> 13 | <li 14 | className={cn( 15 | "flex px-1 items-center transition-all duration-500 ease-linear text-theme-500 hover:text-primary-focus" 16 | )} 17 | > 18 | <Link href={"/"}> 19 | <a className={cn("no-underline rounded-md uppercase font-medium ")}> 20 | 主页 21 | </a> 22 | </Link> 23 | <FaChevronRight className={cn("pl-1 inline text-xs")} /> 24 | </li> 25 | {crumbs.map((c, i) => ( 26 | <li 27 | key={i} 28 | className={cn( 29 | "flex px-1 items-center transition-all duration-500 ease-linear text-theme-500 hover:text-primary-focus" 30 | )} 31 | > 32 | <Link href={c.route}> 33 | <a className={cn("no-underline rounded-md uppercase font-medium ")}> 34 | {c.title} 35 | </a> 36 | </Link> 37 | {i !== crumbs.length - 1 && ( 38 | <FaChevronRight className={cn("pl-1 inline text-xs")} /> 39 | )} 40 | </li> 41 | ))} 42 | </ul> 43 | ); 44 | }; 45 | -------------------------------------------------------------------------------- /components/DocComponents/Card.tsx: -------------------------------------------------------------------------------- 1 | import { FC, ReactNode } from "react"; 2 | import classNames from "classnames"; 3 | 4 | export const Card: FC<{ 5 | children: ReactNode; 6 | className?: string; 7 | shadow?: boolean; 8 | dark?: boolean; 9 | }> = ({ children, className, shadow = false, dark = false }) => { 10 | return ( 11 | <div 12 | className={classNames( 13 | "overflow-hidden rounded-2xl border", 14 | dark 15 | ? "border-gray-800 bg-gray-900" 16 | : "border-gray-100 bg-gray-50 dark:border-gray-800 dark:bg-gray-900", 17 | shadow && 18 | `shadow-lg ${ 19 | dark ? "shadow-gray-900" : "shadow-gray-100 dark:shadow-gray-900" 20 | }`, 21 | className 22 | )} 23 | > 24 | {children} 25 | </div> 26 | ); 27 | }; 28 | -------------------------------------------------------------------------------- /components/DocComponents/Cards/Danger.tsx: -------------------------------------------------------------------------------- 1 | import { FC, ReactNode } from "react"; 2 | import configs from "../../../daymd.config"; 3 | export const Danger: React.FC<{ 4 | children: ReactNode; 5 | title?: string | ""; 6 | className?: string | ""; 7 | }> = ({ children, className, title }) => { 8 | return ( 9 | <div 10 | className={`my-5 h-min w-full rounded-lg border-2 border-red-200 bg-red-50 bg-opacity-25 dark:border-red-900/50 dark:bg-red-900/20 ${className}`} 11 | > 12 | <div className="flex h-max items-center space-x-4 p-6 py-4 text-red-500 dark:text-red-300"> 13 | <div className="h-5 font-bold">{configs.cardsInDoc.Danger}</div> 14 | <div className="h-5 font-normal">{title}</div> 15 | </div> 16 | <div className="break-all text-content h-max pl-6 pr-6 mb-5"> 17 | {children} 18 | </div> 19 | </div> 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /components/DocComponents/Cards/Example.tsx: -------------------------------------------------------------------------------- 1 | import { FC, ReactNode } from "react"; 2 | import configs from "../../../daymd.config"; 3 | export const Example: React.FC<{ 4 | children: ReactNode; 5 | title?: string | ""; 6 | className?: string | ""; 7 | }> = ({ children, className, title }) => { 8 | return ( 9 | <div 10 | className={`my-5 h-min w-full rounded-lg border-2 border-pink-200 bg-pink-50 bg-opacity-25 ${className}`} 11 | > 12 | <div className="flex h-max items-center space-x-4 p-6 py-4 text-pink-500"> 13 | <div className="h-5 font-bold">{configs.cardsInDoc.Example}</div> 14 | <div className="h-5 font-normal">{title}</div> 15 | </div> 16 | <div className="break-all text-content h-max pl-6 pr-6 mb-5"> 17 | {children} 18 | </div> 19 | </div> 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /components/DocComponents/Cards/Note.tsx: -------------------------------------------------------------------------------- 1 | import { FC, ReactNode } from "react"; 2 | import configs from "../../../daymd.config"; 3 | export const Note: React.FC<{ 4 | children: ReactNode; 5 | title?: string | ""; 6 | className?: string | ""; 7 | }> = ({ children, className, title }) => { 8 | return ( 9 | <div 10 | className={`my-5 h-min w-full rounded-lg border-2 border-blue-200 bg-blue-50 bg-opacity-25 dark:border-blue-900/50 dark:bg-blue-900/20 ${className}`} 11 | > 12 | <div className="flex h-max items-center space-x-4 p-6 py-4 text-blue-500"> 13 | <div className="h-5 font-bold">{configs.cardsInDoc.Note}</div> 14 | <div className="h-5 font-normal">{title}</div> 15 | </div> 16 | <div className="break-all text-content h-max pl-6 pr-6 mb-5"> 17 | {children} 18 | </div> 19 | </div> 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /components/DocComponents/Cards/Tips.tsx: -------------------------------------------------------------------------------- 1 | import { FC, ReactNode } from "react"; 2 | import configs from "../../../daymd.config"; 3 | export const Tips: React.FC<{ 4 | children: ReactNode; 5 | title?: string | ""; 6 | className?: string | ""; 7 | }> = ({ children, className, title }) => { 8 | return ( 9 | <div 10 | className={`my-5 h-min w-full rounded-lg border-2 border-green-200 bg-green-50 bg-opacity-25 dark:border-green-900/50 dark:bg-green-900/20 ${className}`} 11 | > 12 | <div className="flex h-max items-center space-x-4 p-6 py-4 text-green-500 dark:text-green-300"> 13 | <div className="h-5 font-bold">{configs.cardsInDoc.Tip}</div> 14 | <div className="h-5 font-normal">{title}</div> 15 | </div> 16 | <div className="break-all text-content h-max pl-6 pr-6 mb-5"> 17 | {children} 18 | </div> 19 | </div> 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /components/DocComponents/Cards/To.tsx: -------------------------------------------------------------------------------- 1 | // markdown跳转组件 2 | import { FC, ReactNode } from "react"; 3 | import Link from "next/link"; 4 | export const To: React.FC<{ 5 | children: ReactNode; 6 | to: string; 7 | className?: string | ""; 8 | }> = ({ children, className, to }) => { 9 | return ( 10 | <a href={to} style={{ textDecoration: "none" }} target={"_blank"}> 11 | <button className={`btn mx-1 btn-primary btn-sm ${className}`}> 12 | {children} 13 | </button> 14 | </a> 15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /components/DocComponents/Cards/Warn.tsx: -------------------------------------------------------------------------------- 1 | import { FC, ReactNode } from "react"; 2 | import configs from "../../../daymd.config"; 3 | export const Warn: React.FC<{ 4 | children: ReactNode; 5 | title?: string | ""; 6 | className?: string | ""; 7 | }> = ({ children, className, title }) => { 8 | return ( 9 | <div 10 | className={`my-5 h-min w-full rounded-lg border-2 border-yellow-200 bg-yellow-50 bg-opacity-25 dark:border-yellow-900/50 dark:bg-yellow-900/20 ${className}`} 11 | > 12 | <div className="flex h-max items-center space-x-4 p-6 py-4 text-yellow-500 dark:text-violet-300"> 13 | {/* <div className="mt-1 h-5 w-5 shrink-0 text-violet-600"> 14 | <Icon name="exclamation" /> 15 | </div> */} 16 | <div className="h-5 font-bold">{configs.cardsInDoc.Warning}</div> 17 | <div className="h-5 font-normal">{title}</div> 18 | </div> 19 | <div className="break-all text-content h-max pl-6 pr-6 mb-5"> 20 | {children} 21 | </div> 22 | </div> 23 | ); 24 | }; 25 | -------------------------------------------------------------------------------- /components/DocComponents/Collapse.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | export function Collapses(props) { 3 | const [isCollapsed, setIsCollapsed] = React.useState(props.collapsed); 4 | const style = { 5 | collapsed: { 6 | display: "none", 7 | }, 8 | expanded: { 9 | display: "block", 10 | }, 11 | buttonStyle: { 12 | display: "block", 13 | }, 14 | }; 15 | 16 | return ( 17 | <div className="ml-5 mb-5 w-max flex flex-col justify-center items-center"> 18 | <button 19 | className="mx-5 mt-5 btn btn-block btn-outline btn-ghost" 20 | style={style.buttonStyle} 21 | onClick={() => setIsCollapsed(!isCollapsed)} 22 | > 23 | {isCollapsed ? "OPEN" : "CLOSE"} Menu 24 | </button> 25 | <div 26 | className="h-max w-max mt-3" 27 | // 决定显示和折叠 28 | style={isCollapsed ? style.collapsed : style.expanded} 29 | // aria-expanded 是给 Screen Reader 用来 判断当前元素状态的辅助属性 30 | aria-expanded={isCollapsed} 31 | > 32 | {props.children} 33 | </div> 34 | </div> 35 | ); 36 | } 37 | -------------------------------------------------------------------------------- /components/DocComponents/HeadSidebar.tsx: -------------------------------------------------------------------------------- 1 | import type React from "react"; 2 | import cn from "classnames"; 3 | import { useTranslation } from "next-i18next"; 4 | import { PostTree } from "./PostTree"; 5 | import { TNode } from "../../utils/generate-docs-tree"; 6 | import configs from "daymd.config"; 7 | import { Collapses } from "./Collapse"; 8 | 9 | export const HeadSidebar: React.FC<{ tree: TNode[] }> = ({ tree }) => { 10 | const { t } = useTranslation("common"); 11 | return ( 12 | // {configs.smListName} 13 | <div className=" xl:hidden flex flex-col items-center"> 14 | <Collapses> 15 | <nav 16 | className={cn("z-10 w-64 relative grow overflow-y-scroll scrollbar")} 17 | > 18 | <PostTree tree={tree} level={0} /> 19 | </nav> 20 | </Collapses> 21 | </div> 22 | ); 23 | }; 24 | -------------------------------------------------------------------------------- /components/DocComponents/Headings.tsx: -------------------------------------------------------------------------------- 1 | import type React from "react"; 2 | import cn from "classnames"; 3 | 4 | const getHeadingText = (node: React.ReactNode): string => { 5 | if (typeof node === "string") return node.toLowerCase(); 6 | 7 | if (typeof node === "number") return node.toString(); 8 | 9 | if (node instanceof Array) 10 | return node.map(getHeadingText).join("").toLowerCase(); 11 | 12 | if (typeof node === "object" && (node as any)?.props?.children) 13 | return getHeadingText(node as any).toLowerCase(); 14 | 15 | return ""; 16 | }; 17 | 18 | const styles = { 19 | prefix: cn( 20 | "absolute -left-6 inset-y-0 flex items-center cursor-pointer text-transparent", 21 | "group-hover:text-gray-200 dark:group-hover:text-gray-700" 22 | ), 23 | heading: cn("group relative"), 24 | }; 25 | 26 | export const H2: React.FC<React.PropsWithChildren<{}>> = ({ children }) => { 27 | const slug = getHeadingText(children); 28 | 29 | return ( 30 | <h2 id={slug} className={styles.heading}> 31 | <span 32 | onClick={() => (window.location.hash = `#${slug}`)} 33 | className={cn(styles.prefix, "text-2xl")} 34 | > 35 | # 36 | </span> 37 | {children} 38 | </h2> 39 | ); 40 | }; 41 | 42 | export const H3: React.FC<React.PropsWithChildren<{}>> = ({ children }) => { 43 | const slug = getHeadingText(children); 44 | 45 | return ( 46 | <h3 id={slug} className={styles.heading}> 47 | <span 48 | onClick={() => (window.location.hash = `#${slug}`)} 49 | className={cn(styles.prefix, "text-xl")} 50 | > 51 | # 52 | </span> 53 | {children} 54 | </h3> 55 | ); 56 | }; 57 | 58 | export const H4: React.FC<React.PropsWithChildren<{}>> = ({ children }) => { 59 | const slug = getHeadingText(children); 60 | 61 | return ( 62 | <h4 id={slug} className={styles.heading}> 63 | <span 64 | onClick={() => (window.location.hash = `#${slug}`)} 65 | className={cn(styles.prefix, "text-lg")} 66 | > 67 | # 68 | </span> 69 | {children} 70 | </h4> 71 | ); 72 | }; 73 | 74 | export const H5: React.FC<React.PropsWithChildren<{}>> = ({ children }) => { 75 | const slug = getHeadingText(children); 76 | 77 | return ( 78 | <h5 id={slug} className={styles.heading}> 79 | <span 80 | onClick={() => (window.location.hash = `#${slug}`)} 81 | className={cn(styles.prefix, "text-base")} 82 | > 83 | # 84 | </span> 85 | {children} 86 | </h5> 87 | ); 88 | }; 89 | 90 | export const H6: React.FC<React.PropsWithChildren<{}>> = ({ children }) => { 91 | const slug = getHeadingText(children); 92 | 93 | return ( 94 | <h6 id={slug} className={styles.heading}> 95 | <span 96 | onClick={() => (window.location.hash = `#${slug}`)} 97 | className={cn(styles.prefix, "text-sm")} 98 | > 99 | # 100 | </span> 101 | {children} 102 | </h6> 103 | ); 104 | }; 105 | -------------------------------------------------------------------------------- /components/DocComponents/Icon/Exclamation.tsx: -------------------------------------------------------------------------------- 1 | import { FC } from "react"; 2 | 3 | export const ExclamationIcon: FC = () => { 4 | return ( 5 | <svg 6 | xmlns="http://www.w3.org/2000/svg" 7 | fill="current" 8 | viewBox="0 0 512 512" 9 | > 10 | <path d="M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM232 152C232 138.8 242.8 128 256 128s24 10.75 24 24v128c0 13.25-10.75 24-24 24S232 293.3 232 280V152zM256 400c-17.36 0-31.44-14.08-31.44-31.44c0-17.36 14.07-31.44 31.44-31.44s31.44 14.08 31.44 31.44C287.4 385.9 273.4 400 256 400z" /> 11 | </svg> 12 | ); 13 | }; 14 | -------------------------------------------------------------------------------- /components/DocComponents/Icon/index.tsx: -------------------------------------------------------------------------------- 1 | import { FC } from "react"; 2 | 3 | import { ExclamationIcon } from "./Exclamation"; 4 | 5 | export type IconName = "exclamation"; 6 | 7 | const iconMap = { 8 | exclamation: ExclamationIcon, 9 | }; 10 | 11 | export const Icon: FC<{ name: IconName }> = ({ name }) => { 12 | const IconComponent = iconMap[name]; 13 | return <IconComponent />; 14 | }; 15 | -------------------------------------------------------------------------------- /components/DocComponents/PostIndexBar.tsx: -------------------------------------------------------------------------------- 1 | import type React from "react"; 2 | import cn from "classnames"; 3 | import Link from "next/link"; 4 | import { useTranslation } from "next-i18next"; 5 | import { FaGithubAlt } from "react-icons/fa"; 6 | 7 | import { IconJuejin } from "../icons"; 8 | import { SearchIn } from "./SearchIn"; 9 | import { PostIndexTree } from "./PostIndexTree"; 10 | import { TNode } from "../../utils/generate-posts-tree"; 11 | 12 | export const PostIndexBar: React.FC<{ tree: TNode[] }> = ({ tree }) => { 13 | const { t } = useTranslation("common"); 14 | return <PostIndexTree tree={tree.reverse()} level={0} />; 15 | }; 16 | -------------------------------------------------------------------------------- /components/DocComponents/PostIndexTree.tsx: -------------------------------------------------------------------------------- 1 | import type React from "react"; 2 | import { useState } from "react"; 3 | import cn from "classnames"; 4 | import Link from "next/link"; 5 | import { useRouter } from "next/router"; 6 | import Parallax from "react-rellax"; 7 | import { motion, Variants } from "framer-motion"; 8 | import moment from "moment"; 9 | import { FaChevronRight } from "react-icons/fa"; 10 | import { TNode } from "../../utils/generate-posts-tree"; 11 | import { useMount } from "react-use"; 12 | 13 | interface TreeProps { 14 | tree: TNode[]; 15 | level: number; 16 | } 17 | 18 | export const PostIndexTree: React.FC<TreeProps> = ({ tree, level }) => ( 19 | <ul 20 | className={cn( 21 | "relative space-y-2", 22 | level > 0 ? "ml-4 text-base" : "text-lg" 23 | )} 24 | > 25 | {tree && 26 | tree.map((node, index) => ( 27 | <TNodes key={index} node={node} level={level} /> 28 | ))} 29 | </ul> 30 | ); 31 | 32 | interface TreeNodeProps { 33 | node: TNode; 34 | level: number; 35 | } 36 | 37 | const TNodes: React.FC<TreeNodeProps> = ({ node, level }) => { 38 | const { asPath } = useRouter(); 39 | // When page loaded, check the expand navigation. 40 | const [activeRoute] = asPath.match(/^([\/\w\-]+)/) || []; 41 | const isNodeUncollapsed = 42 | // level 1 43 | activeRoute === node.route || 44 | // level 2 45 | activeRoute.split("/").slice(0, 3).join("/") === node.route || 46 | // level 3 47 | activeRoute.split("/").slice(0, 4).join("/") === node.route; 48 | 49 | const [uncollapsed, setUncollapsed] = useState(isNodeUncollapsed); 50 | 51 | // When click the level 2 cate, keep the level 1 expanded. 52 | const cateRouteEqualed = 53 | activeRoute.split("/").slice(0, 3).join("/") === 54 | node.route.split("/").slice(0, 3).join("/"); 55 | 56 | const [variants, setVariants] = useState<Variants>(); 57 | 58 | useMount(() => { 59 | setVariants({ 60 | visible: { 61 | height: "min-content", 62 | opacity: 1, 63 | transition: { duration: 0.3 }, 64 | }, 65 | hidden: { 66 | height: 0, 67 | opacity: 0, 68 | }, 69 | }); 70 | }); 71 | 72 | return ( 73 | <li className={cn("relative")}> 74 | <TreeNodeLink 75 | desc={node.desc} 76 | title={node.title} 77 | date={node.date} 78 | backpic={node.backpic} 79 | route={node.route} 80 | level={level} 81 | activeRoute={activeRoute} 82 | collapsible={node.children.length > 0} 83 | // Make the level 2 uncollapsed change by click, and level 1 uncollapsed by path change. 84 | uncollapsed={cateRouteEqualed && uncollapsed} 85 | onClick={() => setUncollapsed(level === 0 || !uncollapsed)} 86 | /> 87 | {node.children.length > 0 && cateRouteEqualed && ( 88 | <motion.div 89 | variants={variants} 90 | initial="hidden" 91 | animate={uncollapsed ? "visible" : "hidden"} 92 | className={cn( 93 | "mt-2", 94 | // Remove animation when locale changed. 95 | uncollapsed || "h-0 opacity-0 duration-0" 96 | )} 97 | > 98 | <PostIndexTree tree={node.children} level={level + 1} /> 99 | </motion.div> 100 | )} 101 | </li> 102 | ); 103 | }; 104 | 105 | interface TreeNodeLinkProps { 106 | desc: string; 107 | date: string; 108 | title: string; 109 | backpic?: string; 110 | route: string; 111 | level: number; 112 | activeRoute: string; 113 | collapsible: boolean; 114 | uncollapsed: boolean; 115 | onClick: () => void; 116 | } 117 | 118 | const TreeNodeLink: React.FC<TreeNodeLinkProps> = ({ 119 | title, 120 | desc, 121 | date, 122 | route, 123 | backpic, 124 | level, 125 | activeRoute, 126 | collapsible, 127 | uncollapsed, 128 | onClick, 129 | }) => ( 130 | <Link href={route}> 131 | <div className="w-full cursor-pointer my-2"> 132 | <div 133 | style={{ backgroundImage: backpic }} 134 | className="bg-base-100 hover:opacity-80 transition-all duration-1000 ease-in-out bg-no-repeat bg-cover card h-42 shadow-xl image-full" 135 | > 136 | <div className="card-body w-full"> 137 | <h2 className="card-title font-bold text-2xl">{title}</h2> 138 | <p className="text-sm font-mono"> 139 | {moment(date).format("YYYY-MM-DD")} 140 | </p> 141 | <p className="text-base">{desc}</p> 142 | </div> 143 | </div> 144 | </div> 145 | </Link> 146 | ); 147 | -------------------------------------------------------------------------------- /components/DocComponents/PostList.tsx: -------------------------------------------------------------------------------- 1 | import { PostTree } from "./PostTree"; 2 | import { TNode } from "../../utils/generate-docs-tree"; 3 | export const PostList: React.FC<{ tree: TNode[] }> = ({ tree }) => { 4 | console.log("WW" + tree); 5 | return <PostTree tree={tree} level={0} />; 6 | }; 7 | -------------------------------------------------------------------------------- /components/DocComponents/PostSidebar.tsx: -------------------------------------------------------------------------------- 1 | import type React from "react"; 2 | import cn from "classnames"; 3 | import Link from "next/link"; 4 | import { useTranslation } from "next-i18next"; 5 | import { FaGithubAlt } from "react-icons/fa"; 6 | 7 | import { IconJuejin } from "../icons"; 8 | import { SearchIn } from "./SearchIn"; 9 | import { PostTree } from "./PostTree"; 10 | import { TNode } from "../../utils/generate-docs-tree"; 11 | 12 | export const PostSidebar: React.FC<{ tree: TNode[] }> = ({ tree }) => { 13 | const { t } = useTranslation("common"); 14 | return ( 15 | <aside 16 | style={{ position: "sticky", top: "0" }} 17 | className={cn("hidden xl:flex sticky ml-9 mt-7 max-h-screen flex-col ")} 18 | > 19 | <div className="grow flex flex-col space-y-4 pl-2 pr-2 py-2 overflow-y-hidden"> 20 | <div className="text-lg font-black">最新博客</div> 21 | <nav 22 | className={cn("z-0 w-64 relative grow overflow-y-scroll scrollbar")} 23 | > 24 | <PostTree tree={tree.reverse()} level={0} /> 25 | </nav> 26 | <div className={cn("flex flex-col items-center space-y-2")}> 27 | <div className={cn("flex space-x-6")}></div> 28 | </div> 29 | </div> 30 | </aside> 31 | ); 32 | }; 33 | -------------------------------------------------------------------------------- /components/DocComponents/PostTree.tsx: -------------------------------------------------------------------------------- 1 | import type React from "react"; 2 | import { useState } from "react"; 3 | import cn from "classnames"; 4 | import Link from "next/link"; 5 | import { useRouter } from "next/router"; 6 | 7 | import { motion, Variants } from "framer-motion"; 8 | 9 | import { FaChevronRight } from "react-icons/fa"; 10 | import { TNode } from "../../utils/generate-docs-tree"; 11 | import { useMount } from "react-use"; 12 | 13 | interface TreeProps { 14 | tree: TNode[]; 15 | level: number; 16 | } 17 | 18 | export const PostTree: React.FC<TreeProps> = ({ tree, level }) => ( 19 | <ul 20 | className={cn( 21 | "relative space-y-2", 22 | level > 0 ? "ml-4 text-base" : "text-lg" 23 | )} 24 | > 25 | {tree && 26 | tree.map((node, index) => ( 27 | <TNodes key={index} node={node} level={level} /> 28 | ))} 29 | </ul> 30 | ); 31 | 32 | interface TreeNodeProps { 33 | node: TNode; 34 | level: number; 35 | } 36 | 37 | const TNodes: React.FC<TreeNodeProps> = ({ node, level }) => { 38 | const { asPath } = useRouter(); 39 | // When page loaded, check the expand navigation. 40 | const [activeRoute] = asPath.match(/^([\/\w\-]+)/) || []; 41 | const isNodeUncollapsed = 42 | // level 1 43 | activeRoute === node.route || 44 | // level 2 45 | activeRoute.split("/").slice(0, 3).join("/") === node.route || 46 | // level 3 47 | activeRoute.split("/").slice(0, 4).join("/") === node.route; 48 | 49 | const [uncollapsed, setUncollapsed] = useState(isNodeUncollapsed); 50 | 51 | // When click the level 2 cate, keep the level 1 expanded. 52 | const cateRouteEqualed = 53 | activeRoute.split("/").slice(0, 3).join("/") === 54 | node.route.split("/").slice(0, 3).join("/"); 55 | 56 | const [variants, setVariants] = useState<Variants>(); 57 | 58 | useMount(() => { 59 | setVariants({ 60 | visible: { 61 | height: "min-content", 62 | opacity: 1, 63 | transition: { duration: 0.3 }, 64 | }, 65 | hidden: { 66 | height: 0, 67 | opacity: 0, 68 | }, 69 | }); 70 | }); 71 | 72 | return ( 73 | <li className={cn("relative")}> 74 | <TreeNodeLink 75 | title={node.title} 76 | route={node.route} 77 | level={level} 78 | activeRoute={activeRoute} 79 | collapsible={node.children.length > 0} 80 | // Make the level 2 uncollapsed change by click, and level 1 uncollapsed by path change. 81 | uncollapsed={cateRouteEqualed && uncollapsed} 82 | onClick={() => setUncollapsed(level === 0 || !uncollapsed)} 83 | /> 84 | {node.children.length > 0 && cateRouteEqualed && ( 85 | <motion.div 86 | variants={variants} 87 | initial="hidden" 88 | animate={uncollapsed ? "visible" : "hidden"} 89 | className={cn( 90 | "mt-2", 91 | // Remove animation when locale changed. 92 | uncollapsed || "h-0 opacity-0 duration-0" 93 | )} 94 | > 95 | <PostTree tree={node.children} level={level + 1} /> 96 | </motion.div> 97 | )} 98 | </li> 99 | ); 100 | }; 101 | 102 | interface TreeNodeLinkProps { 103 | title: string; 104 | route: string; 105 | level: number; 106 | activeRoute: string; 107 | collapsible: boolean; 108 | uncollapsed: boolean; 109 | onClick: () => void; 110 | } 111 | 112 | const TreeNodeLink: React.FC<TreeNodeLinkProps> = ({ 113 | title, 114 | route, 115 | level, 116 | activeRoute, 117 | collapsible, 118 | uncollapsed, 119 | onClick, 120 | }) => ( 121 | <Link href={route}> 122 | <a className="z-0" onClick={onClick}> 123 | <span 124 | className={cn( 125 | "flex font-normal antialiased transition-all duration-500 ease-in-out text-base z-0 items-center justify-between py-1 rounded-md", 126 | route === activeRoute ? " text-accent" : "", 127 | !collapsible && level > 0 ? "font-light" : "py-1" 128 | )} 129 | > 130 | {title} 131 | {collapsible && ( 132 | <FaChevronRight 133 | className={cn( 134 | "shrink-0 text-sm transition-transform duration-300", 135 | route === activeRoute 136 | ? "text-theme-500 dark:text-theme-500" 137 | : "text-gray-300 dark:text-gray-500", 138 | uncollapsed && "rotate-90" 139 | )} 140 | /> 141 | )} 142 | </span> 143 | </a> 144 | </Link> 145 | ); 146 | -------------------------------------------------------------------------------- /components/DocComponents/SearchIn.jsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link"; 2 | import cn from "classnames"; 3 | function SearchBar() { 4 | return ( 5 | <div class="group"> 6 | <svg class="icon" aria-hidden="true" viewBox="0 0 24 24"> 7 | <g> 8 | <path d="M21.53 20.47l-3.66-3.66C19.195 15.24 20 13.214 20 11c0-4.97-4.03-9-9-9s-9 4.03-9 9 4.03 9 9 9c2.215 0 4.24-.804 5.808-2.13l3.66 3.66c.147.146.34.22.53.22s.385-.073.53-.22c.295-.293.295-.767.002-1.06zM3.5 11c0-4.135 3.365-7.5 7.5-7.5s7.5 3.365 7.5 7.5-3.365 7.5-7.5 7.5-7.5-3.365-7.5-7.5z"></path> 9 | </g> 10 | </svg> 11 | <input placeholder="Search" type="search" class="input" /> 12 | </div> 13 | ); 14 | } 15 | 16 | export function SearchIn() { 17 | return <SearchBar />; 18 | } 19 | -------------------------------------------------------------------------------- /components/DocComponents/Sidebar.tsx: -------------------------------------------------------------------------------- 1 | import type React from "react"; 2 | import cn from "classnames"; 3 | import { useTranslation } from "next-i18next"; 4 | import { Tree } from "./Tree"; 5 | import { TNode } from "../../utils/generate-docs-tree"; 6 | let isCollapsed = true; 7 | export const Sidebar: React.FC<{ tree: TNode[] }> = ({ tree }) => { 8 | const { t } = useTranslation("common"); 9 | const style = { 10 | collapsed: { 11 | display: "none", 12 | }, 13 | expanded: { 14 | display: "flex", 15 | }, 16 | buttonStyle: { 17 | display: "flex", 18 | }, 19 | }; 20 | return ( 21 | <div style={{ position: "sticky", top: "0" }}> 22 | <aside 23 | className={cn( 24 | "xl:flex hidden sticky border-r-2 border-opacity-25 border-blue-100 max-h-screen flex-col " 25 | )} 26 | 27 | // style={isCollapsed ? style.collapsed : style.expanded} 28 | // aria-expanded={true} 29 | > 30 | <div className="grow flex flex-col space-y-4 pl-2 pr-2 py-2 overflow-y-hidden"> 31 | <nav 32 | className={cn("z-0 w-64 relative grow overflow-y-scroll scrollbar")} 33 | > 34 | <Tree tree={tree} level={0} /> 35 | </nav> 36 | <div className={cn("flex flex-col items-center space-y-2")}> 37 | <div className={cn("flex space-x-6")}></div> 38 | </div> 39 | </div> 40 | </aside> 41 | </div> 42 | ); 43 | }; 44 | -------------------------------------------------------------------------------- /components/DocComponents/Tree.tsx: -------------------------------------------------------------------------------- 1 | import type React from "react"; 2 | import { useState } from "react"; 3 | import cn from "classnames"; 4 | import Link from "next/link"; 5 | import { useRouter } from "next/router"; 6 | 7 | import { motion, Variants } from "framer-motion"; 8 | 9 | import { FaChevronRight } from "react-icons/fa"; 10 | import { TNode } from "../../utils/generate-docs-tree"; 11 | import { useMount } from "react-use"; 12 | 13 | interface TreeProps { 14 | tree: TNode[]; 15 | level: number; 16 | } 17 | 18 | export const Tree: React.FC<TreeProps> = ({ tree, level }) => ( 19 | <ul 20 | className={cn( 21 | "relative space-y-2", 22 | level > 0 ? "ml-4 text-base" : "text-lg" 23 | )} 24 | > 25 | {tree.map((node, index) => ( 26 | <TNodes key={index} node={node} level={level} /> 27 | ))} 28 | </ul> 29 | ); 30 | 31 | interface TreeNodeProps { 32 | node: TNode; 33 | level: number; 34 | } 35 | 36 | const TNodes: React.FC<TreeNodeProps> = ({ node, level }) => { 37 | const { asPath } = useRouter(); 38 | // When page loaded, check the expand navigation. 39 | const [activeRoute] = asPath.match(/^([\/\w\-]+)/) || []; 40 | const isNodeUncollapsed = 41 | // level 1 42 | activeRoute === node.route || 43 | // level 2 44 | activeRoute.split("/").slice(0, 3).join("/") === node.route || 45 | // level 3 46 | activeRoute.split("/").slice(0, 4).join("/") === node.route; 47 | 48 | const [uncollapsed, setUncollapsed] = useState(isNodeUncollapsed); 49 | 50 | // When click the level 2 cate, keep the level 1 expanded. 51 | const cateRouteEqualed = 52 | activeRoute.split("/").slice(0, 3).join("/") === 53 | node.route.split("/").slice(0, 3).join("/"); 54 | 55 | const [variants, setVariants] = useState<Variants>(); 56 | 57 | useMount(() => { 58 | setVariants({ 59 | visible: { 60 | height: "min-content", 61 | opacity: 1, 62 | transition: { duration: 0.3 }, 63 | }, 64 | hidden: { 65 | height: 0, 66 | opacity: 0, 67 | }, 68 | }); 69 | }); 70 | 71 | return ( 72 | <li className={cn("relative")}> 73 | <TreeNodeLink 74 | title={node.title} 75 | route={node.route} 76 | level={level} 77 | activeRoute={activeRoute} 78 | collapsible={node.children.length > 0} 79 | // Make the level 2 uncollapsed change by click, and level 1 uncollapsed by path change. 80 | uncollapsed={cateRouteEqualed && uncollapsed} 81 | onClick={() => setUncollapsed(level === 0 || !uncollapsed)} 82 | /> 83 | {node.children.length > 0 && cateRouteEqualed && ( 84 | <motion.div 85 | variants={variants} 86 | initial="hidden" 87 | animate={uncollapsed ? "visible" : "hidden"} 88 | className={cn( 89 | "mt-2", 90 | // Remove animation when locale changed. 91 | uncollapsed || "h-0 opacity-0 duration-0" 92 | )} 93 | > 94 | <Tree tree={node.children} level={level + 1} /> 95 | </motion.div> 96 | )} 97 | </li> 98 | ); 99 | }; 100 | 101 | interface TreeNodeLinkProps { 102 | title: string; 103 | route: string; 104 | level: number; 105 | activeRoute: string; 106 | collapsible: boolean; 107 | uncollapsed: boolean; 108 | onClick: () => void; 109 | } 110 | 111 | const TreeNodeLink: React.FC<TreeNodeLinkProps> = ({ 112 | title, 113 | route, 114 | level, 115 | activeRoute, 116 | collapsible, 117 | uncollapsed, 118 | onClick, 119 | }) => ( 120 | <Link href={route}> 121 | <a className="z-0" onClick={onClick}> 122 | <span 123 | className={cn( 124 | "flex font-semibold antialiased transition-all duration-500 ease-in-out text-base z-0 items-center justify-between px-3 py-1 rounded-md", 125 | route === activeRoute 126 | ? " text-theme-500 dark:text-theme-500 bg-primary bg-opacity-20 dark:bg-theme-500/10" 127 | : "hover:bg-gray-200/40 hover:dark:bg-gray-800/40", 128 | !collapsible && level > 0 ? "font-light" : "py-1" 129 | )} 130 | > 131 | {title} 132 | {collapsible && ( 133 | <FaChevronRight 134 | className={cn( 135 | "shrink-0 text-sm transition-transform duration-300", 136 | route === activeRoute 137 | ? "text-theme-500 dark:text-theme-500" 138 | : "text-gray-300 dark:text-gray-500", 139 | uncollapsed && "rotate-90" 140 | )} 141 | /> 142 | )} 143 | </span> 144 | </a> 145 | </Link> 146 | ); 147 | -------------------------------------------------------------------------------- /components/DocComponents/WarningBox.jsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link"; 2 | import cn from "classnames"; 3 | function WarningBoxs() { 4 | return ( 5 | <div class="alert alert-warning shadow-lg"> 6 | <div> 7 | <svg 8 | xmlns="http://www.w3.org/2000/svg" 9 | class="stroke-current flex-shrink-0 h-6 w-6" 10 | fill="none" 11 | viewBox="0 0 24 24" 12 | > 13 | <path 14 | strokeLinecap="round" 15 | strokeLinejoin="round" 16 | strokeWidth="2" 17 | d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" 18 | /> 19 | </svg> 20 | <span>Warning: Invalid email address!</span> 21 | </div> 22 | </div> 23 | ); 24 | } 25 | 26 | export function WarningBox() { 27 | return <WarningBoxs />; 28 | } 29 | -------------------------------------------------------------------------------- /components/DocComponents/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./Asides"; 2 | export * from "./Breadcrumbs"; 3 | export * from "./Headings"; 4 | export * from "./SearchIn"; 5 | export * from "./WarningBox"; 6 | export * from "./Card"; 7 | export * from "./Cards/Warn"; 8 | export * from "./Cards/Example"; 9 | export * from "./Cards/To"; 10 | export * from "./Cards/Tips"; 11 | export * from "./Cards/Note"; 12 | export * from "./Cards/Danger"; 13 | export * from "./PostSidebar"; 14 | export * from "./Sidebar"; 15 | export * from "./HeadSidebar"; 16 | export * from "./Collapse"; 17 | export * from "./PostList"; 18 | -------------------------------------------------------------------------------- /components/Feter.jsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link"; 2 | import { useEffect } from "react"; 3 | import { themeChange } from "theme-change"; 4 | import configs from "../daymd.config"; 5 | import styles from "./styles.module.css"; 6 | import Parallax from "react-rellax"; 7 | const FeatureList = [ 8 | { 9 | title: "零基础上手", 10 | file: "https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/banner1.png", 11 | desc: "全面封装API,只需要填写预留的设置选项,就可以快速搭建出个人网站", 12 | }, 13 | { 14 | title: "高度自定义", 15 | file: "https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/banner2.png", 16 | desc: "Next.js应用,可用React快速自定义样式,增加新功能,同时为您预留多种主题", 17 | }, 18 | { 19 | title: "低代码迅速部署上线", 20 | file: "https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/banner3.png", 21 | desc: "不需要任何环境准备,不需要写代码,快速自动化部署上线", 22 | }, 23 | ]; 24 | 25 | function Feature({ file, title, desc }) { 26 | return ( 27 | <div className="w-96 flex flex-col hover:opacity-70 transition duration-500 ease-in-out"> 28 | <div className="text-center flex flex-wrap justify-center"> 29 | <img className="h-80 " src={file} alt="banner" /> 30 | </div> 31 | <div className="text-center pl-10 pr-10"> 32 | <h3 className="text-lg font-bold">{title}</h3> 33 | <p className="text-center text-sm">{desc}</p> 34 | </div> 35 | </div> 36 | ); 37 | } 38 | 39 | export function Feter() { 40 | return ( 41 | <div className="mt-36"> 42 | <div className="w-screen h-10 flex justify-center items-center"> 43 | <span className="mb-20 w-30 text-center font-black largetext"> 44 | Daymd's Features 45 | </span> 46 | </div> 47 | <div className="gap-x-2.5 w-screen mb-10 h-30 "> 48 | <div className="flex flex-1 flex-wrap flex-row justify-around auto-cols-max"> 49 | {FeatureList.map((props, idx) => ( 50 | <Feature key={idx} {...props} /> 51 | ))} 52 | </div> 53 | </div> 54 | </div> 55 | ); 56 | } 57 | -------------------------------------------------------------------------------- /components/Footer.jsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link"; 2 | import { useEffect } from "react"; 3 | import { themeChange } from "theme-change"; 4 | import configs from "../daymd.config"; 5 | function Toggle() { 6 | useEffect(() => { 7 | themeChange(false); 8 | // 👆 false parameter is required for react project 9 | }, []); 10 | return ( 11 | <div> 12 | <select data-choose-theme class="select h-5 w-17 "> 13 | {configs.themeSelect.map((props, idx) => ( 14 | <option key={idx} {...props} value={props.theme}> 15 | {props.theme} 16 | </option> 17 | ))} 18 | </select> 19 | </div> 20 | ); 21 | } 22 | 23 | function Foot() { 24 | return ( 25 | <div> 26 | <footer 27 | style={{ 28 | display: configs.ifFootItems ? "" : "none", 29 | }} 30 | class="z-50 footer p-10 bg-base-200 text-base-content" 31 | > 32 | {configs.FooterItems.map((props, idx) => ( 33 | <div key={idx} {...props}> 34 | <span class="footer-title">{props.label}</span> 35 | {props.items.map((p, i) => ( 36 | <a 37 | href={p.to} 38 | target={p.blank ? "_blank" : ""} 39 | // target={"_blank"} 40 | key={i} 41 | {...p} 42 | class="link link-hover" 43 | > 44 | {p.name} 45 | </a> 46 | ))} 47 | </div> 48 | ))} 49 | {/* 是否显示主题切换 */} 50 | <div 51 | style={{ 52 | display: configs.showTheme ? "" : "none", 53 | }} 54 | > 55 | <span class="footer-title">Theme</span> 56 | <div> 57 | <Toggle /> 58 | </div> 59 | </div> 60 | </footer> 61 | <footer class="footer px-10 py-4 border-t bg-base-200 text-base-content border-base-300"> 62 | <div class="items-center flex-row"> 63 | <div class="avatar"> 64 | <div class="w-11 rounded-xl"> 65 | <img src={configs.footLogo} /> 66 | </div> 67 | </div> 68 | <div> 69 | <strong>{configs.footText}</strong> 70 | <br /> 71 | {configs.footTextNormal} 72 | <br /> 73 | <div className="font-mono"> 74 | Built with{" "} 75 | <a 76 | className="text-primary " 77 | href="https://daymd.netlify.app" 78 | target={"_blank"} 79 | > 80 | Daymd. 81 | </a>{" "} 82 | </div> 83 | </div> 84 | </div> 85 | 86 | <div class="md:place-self-center md:justify-self-end"> 87 | <div 88 | style={{ 89 | display: configs.ifFootTheme ? "" : "none", 90 | }} 91 | > 92 | <div> 93 | <Toggle /> 94 | </div> 95 | </div> 96 | <div class="grid grid-flow-col gap-4"> 97 | {configs.socialIcon.map((props, idx) => ( 98 | <a href={props.to} key={idx} {...props} target={"_blank"}> 99 | <button class=" btn btn-ghost btn-circle"> 100 | <img class="w-8" src={props.icon} alt={props.name} /> 101 | </button> 102 | </a> 103 | ))} 104 | </div> 105 | </div> 106 | </footer> 107 | </div> 108 | ); 109 | } 110 | 111 | export function Footer() { 112 | return <Foot />; 113 | } 114 | -------------------------------------------------------------------------------- /components/Header.tsx: -------------------------------------------------------------------------------- 1 | import Link from 'next/link' 2 | 3 | function Icon() { 4 | return ( 5 | <svg width="22" height="24" viewBox="0 0 22 24" fill="none" xmlns="http://www.w3.org/2000/svg"> 6 | <path 7 | fillRule="evenodd" 8 | clipRule="evenodd" 9 | d="M10.43 0.92268C11.1426 0.398115 12.1177 0.407491 12.82 0.945665L19.9928 6.44198C21.0266 7.23419 21.0266 8.78771 19.9928 9.57992L17.2573 11.6761L20.0379 13.9037C21.0493 14.7139 21.022 16.2574 19.9826 17.0315L12.62 22.5153C11.8634 23.0788 10.8134 23.0332 10.1089 22.4063L4.34789 17.2802L3.54224 16.5903C-0.0530112 13.5114 0.390183 7.84094 4.41274 5.35212L10.43 0.92268ZM16.1955 10.8254L12.8515 8.14659C12.1375 7.57457 11.1235 7.56365 10.3972 8.12017L7.92298 10.0161C6.88913 10.8084 6.88913 12.3619 7.92298 13.1541L10.4154 15.064C11.129 15.6108 12.1224 15.6108 12.836 15.064L16.1773 12.5036L19.2086 14.932C19.5457 15.2021 19.5366 15.7166 19.1901 15.9747L11.8275 21.4585C11.5753 21.6463 11.2253 21.6311 10.9905 21.4221L5.2248 16.2918L4.40495 15.5895C1.48255 13.0869 1.84941 8.47338 5.13088 6.46078L5.15471 6.44617L11.2165 1.98398C11.454 1.80913 11.779 1.81225 12.0132 1.99164L19.1859 7.48796C19.5305 7.75203 19.5305 8.26987 19.1859 8.53394L16.1955 10.8254ZM15.1155 11.653L12.0291 14.018C11.7913 14.2003 11.4601 14.2003 11.2223 14.018L8.72984 12.1081C8.38523 11.844 8.38523 11.3262 8.72984 11.0621L11.2041 9.16615C11.4462 8.98065 11.7842 8.98429 12.0222 9.17496L15.1155 11.653Z" 10 | fill="#7C3AED" 11 | stroke="#7C3AED" 12 | strokeWidth="0.5" 13 | ></path> 14 | </svg> 15 | ) 16 | } 17 | 18 | function Logo() { 19 | return ( 20 | <Link href="/"> 21 | <a className="inline-flex justify-center items-center"> 22 | <span className="mr-2"> 23 | <Icon /> 24 | </span> 25 | <span className="font-bold">Contentlayer</span> 26 | </a> 27 | </Link> 28 | ) 29 | } 30 | 31 | export function Header() { 32 | return ( 33 | <header className="p-8 flex justify-center"> 34 | <Logo /> 35 | </header> 36 | ) 37 | } 38 | -------------------------------------------------------------------------------- /components/Hero.jsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link"; 2 | import configs from "../daymd.config"; 3 | import { ReactNebula } from "@flodlc/nebula"; 4 | function StarHero() { 5 | return ( 6 | <div class="w-screen h-screen"> 7 | <ReactNebula /> 8 | 9 | <ReactNebula 10 | config={{ 11 | // 星星数量,number,要求:<1000 12 | starsCount: configs.heroModeConfig.starsCount, 13 | // 星星颜色,string 14 | starsColor: configs.heroModeConfig.starsColor, 15 | // 星星旋转速度,number 16 | starsRotationSpeed: configs.heroModeConfig.starsRotationSpeed, 17 | // 彗星出现的频度,number,若值设置为0,隐藏彗星 18 | cometFrequence: configs.heroModeConfig.cometFrequence, 19 | // 星云强度,number,即两侧颜色深度 20 | nebulasIntensity: configs.heroModeConfig.nebulasIntensity, 21 | // 太阳系数量,number,若设置为0,隐藏 22 | sunScale: configs.heroModeConfig.sunScale, 23 | // 行星数量,number,若设置为0,隐藏 24 | planetsScale: configs.heroModeConfig.planetsScale, 25 | // 太阳系轨道,number,要求<100 26 | solarSystemOrbite: configs.heroModeConfig.solarSystemOrbite, 27 | // 轨道速度,number 28 | solarSystemSpeedOrbit: configs.heroModeConfig.solarSystemSpeedOrbit, 29 | }} 30 | /> 31 | <div class="text-neutral-content w-screen h-screen z-10 flex justify-center items-center font-black"> 32 | <span class="flex justify-center antialiased text-7xl text-indigo-500 z-10 object-center"> 33 | {configs.heroText} 34 | </span> 35 | </div> 36 | </div> 37 | ); 38 | } 39 | function Heros() { 40 | return ( 41 | <div 42 | class="hero min-h-screen" 43 | style={{ 44 | background: configs.heroBg, 45 | backgroundSize: "cover", 46 | backgroundRepeat: "no-repeat", 47 | }} 48 | > 49 | <div class="hero-overlay bg-opacity-60"></div> 50 | <div class="left-0 z-0 hero-content text-center text-neutral-content"> 51 | <div class="max-w-md"> 52 | <h1 class="text-5xl font-bold">{configs.heroText}</h1> 53 | <p class="z-0 mb-5">{configs.heroContent}</p> 54 | <Link href={configs.heroButtonLink}> 55 | <button 56 | style={{ 57 | display: configs.isHeroButton ? "" : "none", 58 | }} 59 | class="btn btn-primary" 60 | > 61 | {configs.heroButton} 62 | </button> 63 | </Link> 64 | </div> 65 | </div> 66 | </div> 67 | ); 68 | } 69 | 70 | export function Hero() { 71 | if (configs.heroMode === 0) { 72 | // 不显示背景 73 | return ( 74 | <div style={{ display: "none" }}> 75 | <Heros /> 76 | </div> 77 | ); 78 | } else if (configs.heroMode === 1) { 79 | // 图片背景 80 | return <Heros />; 81 | } else if (configs.heroMode === 2) { 82 | // 宇宙背景 83 | return <StarHero />; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /components/NavBar.jsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link"; 2 | import { useEffect } from "react"; 3 | import { themeChange } from "theme-change"; 4 | import configs from "../daymd.config"; 5 | 6 | function Nav() { 7 | return ( 8 | <div 9 | className={`shadow-sm backdrop-blur-md w-screen navbar bg-base-100 ${configs.navOpacity}`} 10 | > 11 | <div class="navbar-start"> 12 | <div style={{ zIndex: "1000" }} class="dropdown"> 13 | <label tabIndex="0" class="btn btn-ghost btn-circle"> 14 | <svg 15 | xmlns="http://www.w3.org/2000/svg" 16 | class="h-5 w-5" 17 | fill="none" 18 | viewBox="0 0 24 24" 19 | stroke="currentColor" 20 | > 21 | <path 22 | strokeLinecap="round" 23 | strokeLinejoin="round" 24 | strokeWidth="2" 25 | d="M4 6h16M4 12h16M4 18h7" 26 | /> 27 | </svg> 28 | </label> 29 | <ul 30 | tabIndex="0" 31 | class="menu menu-compact dropdown-content mt-3 p-2 shadow bg-base-100 rounded-box w-52" 32 | > 33 | {configs.navItems.map((props, idx) => ( 34 | <li key={idx} {...props}> 35 | <Link href={props.to}>{props.name}</Link> 36 | </li> 37 | ))} 38 | </ul> 39 | </div> 40 | </div> 41 | <div class="navbar-center"> 42 | <div class="avatar"> 43 | <div class="w-11 rounded-xl"> 44 | <img 45 | style={{ 46 | display: configs.isNavLogo ? "block" : "none", 47 | }} 48 | src={configs.navLogo} 49 | /> 50 | </div> 51 | </div> 52 | <Link href="/"> 53 | <a class="btn font-sans btn-ghost normal-case text-xl"> 54 | {configs.title} 55 | </a> 56 | </Link> 57 | </div> 58 | 59 | <div class="navbar-end"> 60 | {configs.navIcons.map((props, idx) => ( 61 | <a href={props.to} key={idx} {...props} target={"_blank"}> 62 | <button class="btn btn-ghost btn-circle h-2 p-3"> 63 | <img src={props.icon} alt={props.name} /> 64 | </button> 65 | </a> 66 | ))} 67 | </div> 68 | </div> 69 | ); 70 | } 71 | 72 | function Nav2() { 73 | return ( 74 | <div 75 | className={`shadow-sm backdrop-blur-md w-screen navbar bg-base-100 ${configs.navOpacity}`} 76 | > 77 | <div class="navbar-start"> 78 | <div class="dropdown"> 79 | <label tabIndex="0" class="btn btn-ghost lg:hidden"> 80 | <svg 81 | xmlns="http://www.w3.org/2000/svg" 82 | class="h-5 w-5" 83 | fill="none" 84 | viewBox="0 0 24 24" 85 | stroke="currentColor" 86 | > 87 | <path 88 | strokeLinecap="round" 89 | strokeLinejoin="round" 90 | strokeWidth="2" 91 | d="M4 6h16M4 12h8m-8 6h16" 92 | /> 93 | </svg> 94 | </label> 95 | <ul 96 | tabIndex="0" 97 | class="menu menu-compact dropdown-content mt-3 p-2 shadow bg-base-100 bg-opacity-100 rounded-box w-52" 98 | > 99 | {configs.navItems.map((props, idx) => ( 100 | <li key={idx} {...props}> 101 | <Link href={props.to}>{props.name}</Link> 102 | </li> 103 | ))} 104 | </ul> 105 | </div> 106 | <div class="avatar"> 107 | <div class="w-11 rounded-xl"> 108 | <img 109 | style={{ 110 | display: configs.isNavLogo ? "block" : "none", 111 | }} 112 | src={configs.navLogo} 113 | /> 114 | </div> 115 | </div> 116 | <Link href="/"> 117 | <a class="btn btn-ghost normal-case text-xl">{configs.title}</a> 118 | </Link> 119 | </div> 120 | <div class="navbar-center hidden lg:flex"> 121 | <ul class="menu menu-horizontal p-0"> 122 | {configs.navItems.map((props, idx) => ( 123 | <li key={idx} {...props}> 124 | <Link href={props.to}>{props.name}</Link> 125 | </li> 126 | ))} 127 | </ul> 128 | </div> 129 | <div class="navbar-end"> 130 | {configs.navIcons.map((props, idx) => ( 131 | <a href={props.to} key={idx} {...props} target={"_blank"}> 132 | <button class="btn btn-ghost btn-circle h-2 p-3"> 133 | <img src={props.icon} alt={props.name} /> 134 | </button> 135 | </a> 136 | ))} 137 | </div> 138 | </div> 139 | ); 140 | } 141 | 142 | export function NavBar() { 143 | if (configs.navTheme === 1) { 144 | return <Nav />; 145 | } else if (configs.navTheme === 2) { 146 | return <Nav2 />; 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /components/Powerby.tsx: -------------------------------------------------------------------------------- 1 | import type React from "react"; 2 | import cn from "classnames"; 3 | 4 | export const Poweredby: React.FC = () => ( 5 | <div 6 | className={cn( 7 | "flex flex-col flex-wrap mb-4 mt-10 justify-center items-center" 8 | )} 9 | > 10 | <p className={cn("mr-6 mt-5 text-xs text-center leading-relaxed")}> 11 | Powered by 12 | </p> 13 | <div className={cn("flex items-center flex-wrap")}> 14 | <a 15 | href="https://www.contentlayer.dev/" 16 | className={cn( 17 | "", 18 | "sm:w-64", 19 | "mx-2", 20 | "h-20", 21 | "transition", 22 | "duration-1000", 23 | "ease-in-out", 24 | "hover:opacity-60" 25 | )} 26 | target={"_blank"} 27 | > 28 | <img 29 | className="h-12 sm:h-20" 30 | src="https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/tailwindcss.svg" 31 | alt="" 32 | /> 33 | </a> 34 | <a 35 | href="https://daisyui.com/" 36 | className={cn( 37 | "", 38 | "sm:w-64", 39 | "mx-2", 40 | "h-20", 41 | "transition", 42 | "duration-1000", 43 | "ease-in-out", 44 | "hover:opacity-60" 45 | )} 46 | target={"_blank"} 47 | > 48 | <img 49 | className="h-12 sm:h-20" 50 | src="https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/daisyui.svg" 51 | /> 52 | </a> 53 | <a 54 | href="https://nextjs.org/" 55 | className={cn( 56 | "text-center", 57 | "sm:w-64", 58 | "h-20", 59 | "transition", 60 | "duration-1000", 61 | "ease-in-out", 62 | "hover:opacity-60" 63 | )} 64 | target={"_blank"} 65 | > 66 | <img 67 | className="h-12 sm:h-20" 68 | src="https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/nexticon.svg" 69 | /> 70 | </a> 71 | <a 72 | href="https://tailwindcss.com/" 73 | className={cn( 74 | "sm:w-64", 75 | "mx-2", 76 | "h-20", 77 | "transition", 78 | "duration-1000", 79 | "ease-in-out", 80 | "hover:opacity-60" 81 | )} 82 | target={"_blank"} 83 | > 84 | <img 85 | className="h-12 sm:h-20" 86 | src="https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/twindff.svg" 87 | /> 88 | </a> 89 | </div> 90 | 91 | <a 92 | href="https://netlify.app" 93 | className={cn( 94 | "row-span-3 h-24 mt-3 flex items-center justify-center transition duration-1000 ease-in-out hover:opacity-60" 95 | )} 96 | target={"_blank"} 97 | > 98 | <img 99 | className="h-16 sm:h-24" 100 | src="https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/netlifyicon.svg" 101 | /> 102 | </a> 103 | </div> 104 | ); 105 | -------------------------------------------------------------------------------- /components/RightAuthor.jsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link"; 2 | import configs from "../daymd.config"; 3 | import { ReactNebula } from "@flodlc/nebula"; 4 | 5 | function RightComp() { 6 | return ( 7 | <div className="xl:block hidden cardf justify-center my-2 shadow-xl w-64 rounded-lg h-min border-2 border-primary"> 8 | <figure class="flex justify-center pt-10 "> 9 | <div class="avatar items-center"> 10 | <div class="item-center w-24 rounded-full ring ring-primary ring-offset-base-100 ring-offset-2"> 11 | <img src={configs.theme2Setting.avatar} /> 12 | </div> 13 | </div> 14 | </figure> 15 | <div class="card-body pt-3 items-center text-center"> 16 | <h2 class="card-title">{configs.theme2Setting.authorName}</h2> 17 | <div class="btn-group"> 18 | <Link href="/docs"> 19 | <button class="btn btn-outline btn-primary btn-sm w-14 "> 20 | {configs.theme2Setting.zhan ? "文档" : "Docs"} 21 | </button> 22 | </Link> 23 | <Link href="/posts"> 24 | <button class="btn btn-outline btn-primary btn-sm w-14"> 25 | {configs.theme2Setting.zhan ? "博客" : "Blog"} 26 | </button> 27 | </Link> 28 | </div> 29 | <div className="flex flex-col items-center "> 30 | {configs.theme2Setting.techLinks.map((props, idx) => ( 31 | <div key={idx} {...props} className={`my-1 badge ${props.styles}`}> 32 | {props.tech} 33 | </div> 34 | ))} 35 | </div> 36 | </div> 37 | </div> 38 | ); 39 | } 40 | 41 | function SocialLinks() { 42 | return ( 43 | <div className="p-1 xl:flex flex-wrap hidden items-center justify-center my-2 shadow-xl w-64 rounded-lg h-min border-2 border-primary"> 44 | {configs.theme2Setting.socialIcons.map((props, idx) => ( 45 | <a 46 | className="px-1" 47 | href={props.link} 48 | key={idx} 49 | {...props} 50 | target={"_blank"} 51 | > 52 | <button class="btn btn-ghost btn-square"> 53 | <img className="h-6" src={props.svgPath} alt={props.name} /> 54 | </button> 55 | </a> 56 | ))} 57 | </div> 58 | ); 59 | } 60 | 61 | function MyWords() { 62 | return ( 63 | <div className="p-1 xl:flex flex-wrap hidden items-center justify-center my-2 shadow-xl w-64 rounded-lg h-min border-2 border-primary"> 64 | <p className="text-sm p-4">{configs.theme2Setting.Words}</p> 65 | </div> 66 | ); 67 | } 68 | 69 | export function RightAuthor() { 70 | return ( 71 | <div className="sticky top-20"> 72 | <RightComp /> 73 | <MyWords /> 74 | <SocialLinks /> 75 | </div> 76 | ); 77 | } 78 | -------------------------------------------------------------------------------- /components/ThemeChange.tsx: -------------------------------------------------------------------------------- 1 | import { themeChange } from "theme-change"; 2 | 3 | import { FC, ReactNode } from "react"; 4 | import configs from "../daymd.config"; 5 | import { useEffect } from "react"; 6 | export const ThemeChange: React.FC<{ 7 | title?: string | ""; 8 | }> = ({ title }) => { 9 | useEffect(() => { 10 | themeChange(false); 11 | // 👆 false parameter is required for react project 12 | }, []); 13 | return ( 14 | <div className="w-full h-max grid grid-cols-1 md:grid-cols-5 gap-4 p-5 rounded-md bg-base-200"> 15 | <button 16 | className="btn text-gray-800 bg-gray-200 hover:bg-gray-300 " 17 | data-set-theme="light" 18 | data-act-class="ACTIVECLASS" 19 | > 20 | light 21 | </button> 22 | <button 23 | className="btn text-gray-200 bg-gray-600 hover:bg-gray-700" 24 | data-set-theme="dark" 25 | data-act-class="ACTIVECLASS" 26 | > 27 | dark 28 | </button> 29 | <button 30 | className="btn text-pink-700 bg-pink-300 hover:bg-pink-300" 31 | data-set-theme="valentine" 32 | data-act-class="ACTIVECLASS" 33 | > 34 | valentine 35 | </button> 36 | <button 37 | className="btn text-yellow-700 bg-yellow-200 hover:bg-yellow-300" 38 | data-set-theme="cupcake" 39 | data-act-class="ACTIVECLASS" 40 | > 41 | cupcake 42 | </button> 43 | <button 44 | className="btn text-yellow-700 bg-yellow-400 hover:bg-yellow-500" 45 | data-set-theme="bumblebee" 46 | data-act-class="ACTIVECLASS" 47 | > 48 | bumblebee 49 | </button> 50 | <button 51 | className="btn text-red-700 bg-red-200 hover:bg-red-300" 52 | data-set-theme="emerald" 53 | data-act-class="ACTIVECLASS" 54 | > 55 | emerald 56 | </button> 57 | <button 58 | className="btn text-green-700 bg-green-200 hover:bg-green-300" 59 | data-set-theme="corporate" 60 | data-act-class="ACTIVECLASS" 61 | > 62 | corporate 63 | </button> 64 | <button 65 | className="btn text-purple-700 bg-purple-200 hover:bg-purple-300" 66 | data-set-theme="synthwave" 67 | data-act-class="ACTIVECLASS" 68 | > 69 | synthwave 70 | </button> 71 | <button 72 | className="btn text-yellow-900 bg-yellow-600 hover:bg-yellow-700" 73 | data-set-theme="retro" 74 | data-act-class="ACTIVECLASS" 75 | > 76 | retro 77 | </button> 78 | 79 | <button 80 | className="btn text-yellow-400 bg-yellow-100 hover:bg-yellow-300" 81 | data-set-theme="cyberpunk" 82 | data-act-class="ACTIVECLASS" 83 | > 84 | cyberpunk 85 | </button> 86 | <button 87 | className="btn text-green-700 bg-green-400 hover:bg-green-500" 88 | data-set-theme="halloween" 89 | data-act-class="ACTIVECLASS" 90 | > 91 | halloween 92 | </button> 93 | <button 94 | className="btn text-green-700 bg-green-100 hover:bg-green-200" 95 | data-set-theme="forest" 96 | data-act-class="ACTIVECLASS" 97 | > 98 | forest 99 | </button> 100 | <button 101 | className="btn text-green-900 bg-green-500 hover:bg-green-600" 102 | data-set-theme="garden" 103 | data-act-class="ACTIVECLASS" 104 | > 105 | garden 106 | </button> 107 | <button 108 | className="btn text-blue-700 bg-blue-200 hover:bg-blue-300" 109 | data-set-theme="aqua" 110 | data-act-class="ACTIVECLASS" 111 | > 112 | aqua 113 | </button> 114 | <button 115 | className="btn text-gray-200 bg-gray-700 hover:bg-gray-900" 116 | data-set-theme="lofi" 117 | data-act-class="ACTIVECLASS" 118 | > 119 | lofi 120 | </button> 121 | <button 122 | className="btn text-pink-300 bg-pink-100 hover:bg-pink-200" 123 | data-set-theme="pastel" 124 | data-act-class="ACTIVECLASS" 125 | > 126 | pastel 127 | </button> 128 | <button 129 | className="btn text-pink-500 bg-pink-300 hover:bg-pink-300" 130 | data-set-theme="fantasy" 131 | data-act-class="ACTIVECLASS" 132 | > 133 | fantasy 134 | </button> 135 | <button 136 | className="btn text-gray-700 bg-gray-200 hover:bg-gray-300" 137 | data-set-theme="wireframe" 138 | data-act-class="ACTIVECLASS" 139 | > 140 | wireframe 141 | </button> 142 | <button 143 | className="btn text-gray-100 bg-gray-800 hover:bg-gray-900" 144 | data-set-theme="black" 145 | data-act-class="ACTIVECLASS" 146 | > 147 | black 148 | </button> 149 | <button 150 | className="btn text-yellow-100 bg-yellow-600 hover:bg-yellow-700" 151 | data-set-theme="luxury" 152 | data-act-class="ACTIVECLASS" 153 | > 154 | luxury 155 | </button> 156 | <button 157 | className="btn text-purple-100 bg-purple-400 hover:bg-purple-300" 158 | data-set-theme="dracula" 159 | data-act-class="ACTIVECLASS" 160 | > 161 | dracula 162 | </button> 163 | <button 164 | className="btn text-blue-900 bg-blue-400 hover:bg-blue-500" 165 | data-set-theme="cmyk" 166 | data-act-class="ACTIVECLASS" 167 | > 168 | cmyk 169 | </button> 170 | <button 171 | className="btn text-gray-100 bg-purple-300 hover:bg-purple-400" 172 | data-set-theme="autumn" 173 | data-act-class="ACTIVECLASS" 174 | > 175 | autumn 176 | </button> 177 | <button 178 | className="btn text-gray-100 bg-blue-600 hover:bg-blue-700" 179 | data-set-theme="business" 180 | data-act-class="ACTIVECLASS" 181 | > 182 | business 183 | </button> 184 | <button 185 | className="btn text-green-100 bg-yellow-600 hover:bg-yellow-900" 186 | data-set-theme="coffee" 187 | data-act-class="ACTIVECLASS" 188 | > 189 | coffee 190 | </button> 191 | <button 192 | className="btn text-pink-900 bg-pink-600 hover:bg-pink-700" 193 | data-set-theme="acid" 194 | data-act-class="ACTIVECLASS" 195 | > 196 | acid 197 | </button> 198 | <button 199 | className="btn text-green-900 bg-green-600 hover:bg-green-700" 200 | data-set-theme="lemonade" 201 | data-act-class="ACTIVECLASS" 202 | > 203 | lemonade 204 | </button> 205 | <button 206 | className="btn text-blue-900 bg-blue-600 hover:bg-blue-700" 207 | data-set-theme="night" 208 | data-act-class="ACTIVECLASS" 209 | > 210 | night 211 | </button> 212 | <button 213 | className="btn text-blue-600 bg-blue-200 hover:bg-blue-300" 214 | data-set-theme="winter" 215 | data-act-class="ACTIVECLASS" 216 | > 217 | winter 218 | </button> 219 | </div> 220 | ); 221 | }; 222 | -------------------------------------------------------------------------------- /components/WebsiteCard.tsx: -------------------------------------------------------------------------------- 1 | import React, { memo } from "react"; 2 | import clsx from "clsx"; 3 | import Link from "next/link"; 4 | import styles from "../styles/styles.module.css"; 5 | import { type Website } from "../navData/website"; 6 | 7 | const WebsiteCard = memo(({ website }: { website: Website }) => ( 8 | <li 9 | key={website.name} 10 | className="hover:bg-primary hover:bg-opacity-30 transition-all 1s ease-in-out grid grid-cols-6 justify-items-center p-1 border-2 border-primary rounded-md " 11 | > 12 | <img 13 | src={ 14 | // typeof website.logo === "string" 15 | // ? website.logo 16 | // : (website.logo as any)?.src?.src 17 | website.logo 18 | } 19 | alt={website.name} 20 | className="col-span-2 self-center w-16 h-16 rounded-full ring ring-primary ring-offset-1" 21 | /> 22 | <div className="pl-4 flex flex-col place-content-start self-center col-span-3 content-start"> 23 | <div className={clsx(styles.websiteCardHeader)}> 24 | <h4 className="text-base pt-1 font-bold"> 25 | <a 26 | href={website.href} 27 | target={"_blank"} 28 | className={styles.websiteCardLink} 29 | > 30 | {website.name} 31 | </a> 32 | </h4> 33 | </div> 34 | <p className={styles.websiteCardDesc} data-for="website-desc-tip"> 35 | {website.desc} 36 | </p> 37 | </div> 38 | </li> 39 | )); 40 | 41 | export default WebsiteCard; 42 | -------------------------------------------------------------------------------- /components/icons/IconJujin.tsx: -------------------------------------------------------------------------------- 1 | import type React from 'react' 2 | import cn from 'classnames' 3 | 4 | export const IconJuejin: React.FC<React.SVGAttributes<SVGElement>> = ( 5 | props 6 | ) => ( 7 | <svg 8 | xmlns="http://www.w3.org/2000/svg" 9 | width="18" 10 | height="18" 11 | viewBox="0 0 36 30" 12 | fill="none" 13 | className={cn(props.className)}> 14 | <path 15 | d="M17.5865 17.3955H17.5902L28.5163 8.77432L25.5528 6.39453L17.5902 12.6808H17.5865L17.5828 12.6845L9.62018 6.40201L6.6604 8.78181L17.5828 17.3992L17.5865 17.3955Z" 16 | fill="currentColor" 17 | /> 18 | <path 19 | d="M17.5872 6.77268L21.823 3.40505L17.5872 0.00748237L17.5835 0L13.3552 3.39757L17.5835 6.76894L17.5872 6.77268Z" 20 | fill="currentColor" 21 | /> 22 | <path 23 | d="M17.5865 23.2854L17.5828 23.2891L2.95977 11.7531L0 14.1291L0.284376 14.3574L17.5865 28L28.5238 19.3752L35.1768 14.1254L32.2133 11.7456L17.5865 23.2854Z" 24 | fill="currentColor" 25 | /> 26 | </svg> 27 | ) 28 | -------------------------------------------------------------------------------- /components/icons/index.ts: -------------------------------------------------------------------------------- 1 | export * from './IconJujin' 2 | -------------------------------------------------------------------------------- /components/styles.module.css: -------------------------------------------------------------------------------- 1 | .features { 2 | display: flex; 3 | align-items: center; 4 | padding: 2rem 0; 5 | width: 100%; 6 | z-index: 10000 !important; 7 | } 8 | 9 | 10 | 11 | .featureSvg { 12 | height: 400px; 13 | width: 400px; 14 | } 15 | 16 | /* .featureSvg :hover { 17 | margin-bottom: 20px; 18 | } */ 19 | -------------------------------------------------------------------------------- /content/docs/000-fastgo/000-preparation.zh.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 准备工作 3 | excerpt: 为开发做准备。 4 | date: 2022-08-29 5 | --- 6 | 7 | ## GitHub 8 | 9 | ### 了解 10 | 11 | **什么是 GitHub**?这个名字由两个单词构成:Git 和 Hub。`Git` 是一个流行的版本控制工具,绝大情况下被程序员们用来管理自己写的代码和文档,它的可以接管你的代码文件夹,为其创建历史版本库,比较你修改的代码与历史代码的修改点等。`Hub` 的意思是集散中心、聚集地等意思,这两个词组成了 `GitHub` ,因此 GitHub 是一个开源代码仓库聚集地。我们的 Daymd 代码就存放在上面,因此,我们必须拥有一个 Github 账号。 12 | 13 | ### 注册 14 | 15 | 首先,[Github](https://github.com)处于“半墙”状态,看它主页你就知道为什么了...因此你很可能无法访问,那么你需要一个 boost 或者 ladder。 16 | 搞定 ladder 之后,进入 Github,选择注册,按照流程来就可以。[注册 Github 详细操作](https://blog.csdn.net/m0_59188912/article/details/124912340?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165641220616780357277503%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165641220616780357277503&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~times_rank-1-124912340-null-null.142^v24^huaweicloudv2,157^v15^new_3&utm_term=%E6%B3%A8%E5%86%8Cgithub&spm=1018.2226.3001.4187) 17 | 18 | ### 克隆仓库 19 | 20 | 你将使用我的源码进行网站架构。这需要你**克隆**我的源代码。打开<To to="https://github.com/inannan423/Daymd"> Daymd Github 仓库 </To>,点击右上角按钮 **Fork** ,将我的仓库克隆到你的仓库。 21 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661738426160.png) 22 | 23 | 与此同时,请您顺手点一个 `Star` !拜托了!🙏🙏🙏🙏🙏🙏 24 | 25 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661738496468.png) 26 | 27 | 这时,你就可以在你的 GitHub 仓库中拥有一个 Daymd 副本。 28 | 29 | ## Stackblitz 30 | 31 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220830113728.png) 32 | 33 | ### 介绍 34 | 35 | Stackblitz 是一个在线的代码编辑器,主要聚焦于创建 Web 应用项目。它的最大优点是在浏览器中就可以完成一个完整 Web 应用的构建。它让 `Node.js` 可以在浏览器中运行,这也就帮助我们免去了 Node.js 安装和部署、NPM 安装部署工作。如果你未接触过此类 Web 开发流程,那就跟着这一章节,在浏览器中借助在线 IDE **Stackblitz** 开始一个 Daymd 项目(也就是一个 Next.js 项目)。 36 | 37 | ### 项目导入 38 | 39 | 打开 <To to="https://stackblitz.com/"> Stackblitz 官网 </To> 按照提示,点击创建一个 Next.js 的工程: 40 | 41 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220830113959.png) 42 | 43 | 接着,进入工程界面,点击 `Connect repository`: 44 | 45 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661830846961.png) 46 | 47 | 点击 `import an existing repository` ,导入一个已存在的仓库: 48 | 49 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661830921807.png) 50 | 51 | 接着,到你刚刚 **Fork** 好的仓库(注意是你自己的仓库,名称应该是 `yourgithubid/Daymd` ) 而不是 `inannan423/Daymd` 。复制浏览器地址栏的链接: 52 | 53 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661748964159.png) 54 | 55 | 粘贴到 Stackblitz 导入界面。 56 | 57 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220830114408.png) 58 | 59 | 点击按钮 `import repository` 导入。导入完成后显示如下: 60 | 61 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220830114537.png) 62 | 63 | ### 项目运行 64 | 65 | 这时,需要你重新刷新浏览器。等待重新安装完成。如果依旧如此,请尝试多次刷新。成功之后右边会展示新的预览。 66 | 67 | 点击右上角,`open in new tab`。 68 | 69 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661832062176.png) 70 | 71 | 就可以开始在线编写个人网站啦! 72 | 73 | ### 代码编辑器设置 74 | 75 | 设置代码编辑区字体大小,在设置中的 `User Setting` 中,找到 `"editor.fontSize": 20,` 字段(可以使用 ctrl+F 搜索快速找到),建议值 `20` : 76 | 77 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661903466929.png) 78 | 79 | <Tips> 80 | 下面将介绍 Codesandbox ,实际上它和 Stackblitz 类似,你只需要选择一个使用即可,之后会使用 Stackblitz 演示。 81 | </Tips> 82 | 83 | ## Codesandbox 84 | 85 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220829102247.png) 86 | 87 | ### 介绍 88 | 89 | 同 Stackblitz 一样,CodeSandbox 也是一个在线的代码编辑器,主要聚焦于创建 Web 应用项目。它的最大优点是在浏览器中就可以完成一个完整 Web 应用的构建。它让 `Node.js` 可以在浏览器中运行,这也就帮助我们免去了 Node.js 安装和部署、NPM 安装部署工作。如果你未接触过此类 Web 开发流程,那就跟着这一章节,在浏览器中借助在线 IDE **Codesandbox** 开始一个 Daymd 项目(也就是一个 Next.js 项目)。 90 | 91 | ### 项目导入 92 | 93 | 打开 <To to="https://codesandbox.io/"> Codesandbox 官网 </To> 按照提示,使用 GitHub 登录后,点击右上角的 `Create Sandbox` ,开始一个项目导入。你可以看到下面的界面: 94 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220829124820.png) 95 | 接着,到你刚刚 **Fork** 好的仓库(注意是你自己的仓库,名称应该是 `yourgithubid/Daymd` ) 而不是 `inannan423/Daymd` 。复制浏览器地址栏的链接: 96 | 97 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661748964159.png) 98 | 99 | 粘贴到 Codesandbox 导入界面。 100 | 101 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661749034630.png) 102 | 103 | 点击 `Import and Fork` 按钮,这样,一次导入就完成了。界面如下: 104 | 105 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220829130209.png) 106 | 107 | ### 项目运行 108 | 109 | 等待右边包自动安装完成: 110 | 111 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220829131147.png) 112 | 113 | 进度条安装完成后,就可以在右边小窗口中看到预览。这时,为了更好的预览体验,你可以点击右上角的弹出预览按钮(如下图)。 114 | 115 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661764141590.png) 116 | 117 | 如果没有自动启动完成你可以点击右下角终端中的 + 按钮,添加新终端,输入指令 `npm run dev`: 118 | 119 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661750150292.png) 120 | 121 | 输入指令如下: 122 | 123 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661750213003.png) 124 | 125 | 右下角弹出提示,告知你 `3001` 已经可以开始预览。点击按钮进入即可。 126 | 127 | ![3](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220829134657.png) 128 | 129 | ## 本地运行 130 | 131 | 如同所有的 Web APP 一样,`Daymd` 也可以在本地运行。你可以先克隆我的项目(同时给我一个 Star)。 132 | 133 | ```bash title="git bash" 134 | git clone https://github.com/inannan423/Daymd.git 135 | ``` 136 | 137 | ```bash title="cmd" 138 | npm install 139 | ``` 140 | 141 | ```bash title="cmd" 142 | npm run dev 143 | ``` 144 | 145 | <Tips title="遇到问题?">如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 issue 提交界面.</Tips><To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 146 | -------------------------------------------------------------------------------- /content/docs/000-fastgo/001-content.zh.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 项目结构 3 | excerpt: 认识项目结构 4 | date: 2022-08-29 5 | --- 6 | 在开始对我们的项目进行修改之前,我们需要认识一下项目的结构。因为这里面很多文件是你不需要关注的。 7 | 8 | ## 架构树 9 | 10 | ```bash 11 | daymd 12 | ├── content 13 | │ ├── docs 14 | │ │ ├── index.md 15 | │ │ ├── 000-doc1 16 | │ │ │ ├── index.md 17 | │ │ │ ├── 000-doc11.md 18 | │ │ │ └── 001-doc12.md 19 | │ │ └── 002-doc2 20 | │ │ ├── index.md 21 | │ │ ├── 000-doc11.md 22 | │ │ └── 001-doc12.md 23 | │ └── posts 24 | │ ├── index.md 25 | │ ├── 000-post1 26 | │ │ └── index.md 27 | │ └── 002-post2 28 | │ └── index.md 29 | ├── src 30 | │ ├── configs 31 | │ │ └── ... 32 | │ ├── contentlayer 33 | │ │ └── ... 34 | │ └── themes 35 | │ └── ... 36 | │ 37 | ├── navData 38 | │ ├── friend.ts 39 | │ └── website.ts 40 | │ 41 | ├── components 42 | │ └── ... 43 | │ 44 | ├── .contentlayer 45 | │ └── ... 46 | │ 47 | ├── .next 48 | │ └── ... 49 | │ 50 | ├── pages 51 | │ │ 52 | │ ├── _app.tsx 53 | │ │ 54 | │ ├── index.tsx 55 | │ │ 56 | │ ├── docs 57 | │ │ └── [[...slug]].tsx 58 | │ ├── posts 59 | │ │ └── [[...slug]].tsx 60 | │ └── website 61 | │ └── index.tsx 62 | │ 63 | ├── public 64 | │ ├── images 65 | │ └── locals 66 | │ 67 | ├── styles 68 | ├── typings 69 | ├── utils 70 | ├── contenelayer.config.js 71 | ├── next-env.d.ts 72 | ├── next.config.js 73 | ├── package.json 74 | ├── package-lock.json 75 | ├── README.md 76 | ├── postcss.config.js 77 | ├── tailwind.config.js 78 | ├── tsconfig.json 79 | └── daymd.config.js 80 | ``` 81 | 82 | ## 说明 83 | 84 | 在这个长长的架构树中,有很多都是你不需要关注的,你需要关注的文件只有 `daymd.config.js` 文件、`content` 文件夹以及 `navData` 文件夹。这三个文件(夹)中都不需要编写任何代码。你说的对,我可以把不需要的文件全部封装起来,但是我比较懒😝,以后的版本再说吧。 85 | 86 | - `daymd.config.js` :站点配置文件。这里面封装了全栈所有可以设置的 API ,你可以在这里决定网站的每一个细节。 87 | - `content`:内容文件夹,用于存放文档和博客。 88 | - `navData`:导航数据文件夹,用于存放导航中可以渲染的链接数据。 89 | 90 | 让我们在下一节做一些设置,使你的项目大变样吧(系统化的讲解会在后面,这里只需要跟着做就好了),所有可设置的项目均在 **API** 中展示。 91 | 92 | <Tips title="遇到问题?">如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 issue 提交界面.</Tips><To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 93 | -------------------------------------------------------------------------------- /content/docs/000-fastgo/002-sometry.zh.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 一些尝试 3 | excerpt: 尝试新的东西 4 | date: 2022-08-29 5 | --- 6 | 7 | ## 修改首页样式 8 | 9 | 打开项目全局设置文件 `daymd.config.js` : 10 | 11 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661832533928.png) 12 | 13 | 这里有个 `heroMode` 字段,我们尝试将它从默认值 `3` 更改为 `1` : 14 | 15 | ```js title="修改前" 16 | // 全局API接口 17 | const configs = { 18 | // ... 19 | // hero模式,0:不显示;1:背景图模式;2:宇宙模式;3:博客模式; 20 | heroMode: 3, 21 | //... 22 | }; 23 | ``` 24 | 25 | **修改前的样式**: 26 | 27 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220829190438.png) 28 | 29 | ```js title="修改后" 30 | // 全局API接口 31 | const configs = { 32 | // ... 33 | // hero模式,0:不显示;1:背景图模式;2:宇宙模式;3:博客模式; 34 | heroMode: 1, 35 | //... 36 | }; 37 | ``` 38 | 39 | 按下 `ctrl`+`s` 保存文件,可以看到右边的执行窗口开始刷新,等待刷新完成。在刷新过程中,右下角会出现小三角形: 40 | 41 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661825987922.png) 42 | 43 | 刷新完成后,可以看到样式变成了下面这样: 44 | 45 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220829190246.png) 46 | 47 | ## 添加新的文档 48 | 49 | 打开 `content` 文件夹,再打开 `docs` 文件夹上 `🖱右键` ,创建一个新的文件夹: 50 | 51 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220830120956.png) 52 | 53 | 比如叫 `003-newfolder`,请注意,文件夹必须以 `000-xxxx` 的格式命名,否则会报错: 54 | 55 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661771530648.png) 56 | 57 | 再在 `003-newfolder` 文件夹上面右键,创建新的文件 `index.md` 。贴入下面的内容: 58 | 59 | ```md 60 | --- 61 | title: 我的第一篇文档 62 | excerpt: 文档1 63 | date: 2022-08-29 64 | --- 65 | 66 | ## 一级目录 1 67 | 68 | ### 二级目录 1 69 | 70 | <Tips>你好</Tips> 71 | 72 | ### 二级目录 2 73 | 74 | ## 一级目录 2 75 | ``` 76 | 77 | 按下 `ctrl`+`s` 保存文件,可以看到右边的执行窗口开始刷新,等待刷新完成。刷新完成后 `docs` 页面将会添加一个新的文件夹和一篇新的文章。 78 | 79 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220829195336.png) 80 | 81 | 怎么样?通过上面的尝试,是不是觉得你已经可以开始驾驭 Daymd 了!并没有写任何代码!!(Markdown 文档内容不算代码)。 82 | 从下一章节开始,我们将介绍**如何书写 Markdown 文档**。 83 | 84 | <Tips title="遇到问题?"> 85 | 如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 86 | issue 提交界面. 87 | <To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 88 | </Tips> 89 | -------------------------------------------------------------------------------- /content/docs/000-fastgo/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 快速开始 3 | excerpt: 五分钟内开始一个 Daymd。 4 | date: 2022-08-26 5 | --- 6 | 7 | <Tips> 8 | 在这一章节,我们将花费五分钟的时间,仅仅在**浏览器中**完成整个部署过程。我们需要用到的工具和技术有: 9 | </Tips> 10 | 11 | ## 代码仓库:GitHub 12 | 13 | ![GitHub](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220829091746.png) 14 | 15 | ## 在线 IDE:codesandbox 16 | 17 | ![Codesandbox](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220829092055.png) 18 | 19 | ## 自动部署:Vercel 20 | 21 | ![Vercel](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220829092435.png) 22 | 23 | ## 自动部署:Netlify 24 | 25 | ![Netlify](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220829092558.png) 26 | -------------------------------------------------------------------------------- /content/docs/000-fastgo/index.zh.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 快速开始 3 | excerpt: 五分钟内开始一个 Daymd。 4 | date: 2022-08-26 5 | --- 6 | 7 | <Tips> 8 | 在这一章节,我们将花费五分钟的时间,仅仅在**浏览器中**完成整个部署过程。我们需要用到的工具和技术有: 9 | </Tips> 10 | 11 | ## 代码仓库:GitHub 12 | 13 | ![GitHub](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220829091746.png) 14 | 15 | ## 在线 IDE: Stackblitz 16 | 17 | ![Stackblitz](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220830113340.png) 18 | 19 | ## 在线 IDE:codesandbox 20 | 21 | ![Codesandbox](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220829092055.png) 22 | 23 | ## 自动部署:Vercel 24 | 25 | ![Vercel](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220829092435.png) 26 | 27 | ## 自动部署:Netlify 28 | 29 | ![Netlify](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220829092558.png) 30 | -------------------------------------------------------------------------------- /content/docs/001-docandblog/000-docsstruct.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 文档结构 3 | excerpt: 文档的结构 4 | date: 2022-08-29 5 | --- 6 | 7 | 在本节中,我们将阐述 Daymd 中文档的结构。以便让你清楚创建什么样的结构能够在网站上展示什么样的结果。 8 | 9 | ## 结构树 10 | 11 | 你一定在前面已经见过了下面的结构: 12 | 13 | ```bash 14 | ├── content 15 | │ ├── docs 16 | │ │ ├── index.md 17 | │ │ ├── 000-doc1 18 | │ │ │ ├── index.md 19 | │ │ │ ├── 000-doc11.md 20 | │ │ │ └── 001-doc12.md 21 | │ │ └── 002-doc2 22 | │ │ ├── index.md 23 | │ │ ├── 000-doc11.md 24 | │ │ └── 001-doc12.md 25 | │ └── posts 26 | │ ├── index.md 27 | │ ├── 000-post1 28 | │ │ └── index.md 29 | │ └── 002-post2 30 | │ └── index.md 31 | ... 32 | ``` 33 | 34 | 正如你看到的,`content` 文件夹下被分为了 `docs` 和 `posts` 两个文件夹。它们分别用来存放你的**文档**和**博客**。现在让我们聚焦于文档,在文档中,你可以创建多个集合,每个集合是一个文件夹,每个集合中可以创建多个文件,每一个文件是一个 Markdown 文件也就是一篇文章。 35 | 36 | ## 创建第一个集合 37 | 38 | 在你的个人知识体系中,你可能要存放不同知识领域的东西,这也就要求创建多个集合,每个集合有不同的主题,比如 `Java` 、 `C++`、 `Python` 等等。而在这些主题下都各自对应多篇文章。你可能想构造下面这样的知识体系: 39 | 40 | ```bash 41 | ├── docs 42 | │ ├── index.md // 文档首页 43 | │ ├── 000-Java 44 | │ │ ├── index.md // Java 集合首页 45 | │ │ ├── 000-语法.md // Java 第一篇文章 46 | │ │ └── 001-网络编程.md // Java 第二篇文章 47 | │ └── 002-Python 48 | │ ├── index.md // Python 集合首页 49 | │ ├── 000-语法.md // Python 第一篇文章 50 | │ └── 001-爬虫.md // Python 第二篇文章 51 | ``` 52 | 53 | 这里面就包括了两个集合,因此你需要在 `docs` 文件夹下再创建两个文件夹,名称分别为 `000-Java` 和 `002-Python`。 54 | 55 | 现在,我们创建第一个文件夹,名称为 `000-Java`,然后在这个文件夹下创建两个文件,名称分别为 `000-javalanguage.md` 和 `001-javaweb.md`。如下图: 56 | 57 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661780067153.png) 58 | 59 | <Warn>在项目中,由于要生成链接,因此您的文件名需要使用英文小写字母构成</Warn> 60 | 61 | 不过,在没有内容的情况下,项目很可能无法运行,让我们先简单填充一下,过后再讲解。 62 | 63 | ```md title="index.md" 64 | --- 65 | title: Java 66 | excerpt: 快速上手 67 | date: 2022-08-25 68 | --- 69 | ## Java 70 | ``` 71 | 72 | ```md title="Java语法.md" 73 | --- 74 | title: Java语法 75 | excerpt: 快速上手 76 | date: 2022-08-25 77 | --- 78 | ## Java 79 | ``` 80 | 81 | ```md title="Java网络编程.md" 82 | --- 83 | title: Java网络编程 84 | excerpt: 快速上手 85 | date: 2022-08-25 86 | --- 87 | ``` 88 | 89 | 按下 `ctrl`+`s` 保存文件,可以看到右边的执行窗口开始刷新,等待刷新完成。 90 | 刷新完成后,如下: 91 | 92 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220829213613.png) 93 | 94 | 用相同的操作,你可以创建多个文档集合。 95 | 96 | ## 创建第一个文档 97 | 98 | 在上面创建了第一个集合之后,我们就可以创建**第一个文档**啦!让我们看看一篇标准的文档有什么构成。让我们来思考,我们如何告诉 Daymd 这篇文章的内容,如 **标题**、**简介**、**创建日期**等信息,答案是使用**格式头**。格式头是一种 `yml` 语法,它是一种轻量级的配置文件,可以用来存放一些配置信息。在 Daymd 文档中,我们使用 `yml` 来存放一些配置信息,比如 `title`、`excerpt`、`date` 等等。它放在 Markdown 的头部。 99 | 100 | 一个格式头必须用 `---` 进行包裹,与主要内容区分开。每一篇文档有且仅有一个格式头。 101 | 102 | ```md 103 | --- 104 | title: 文档标题 105 | excerpt: 文档简介 106 | date: 2022-8-25 # 文档创建时间 107 | --- 108 | ## 下面是文档主要内容 109 | ``` 110 | 111 | `title`被渲染在页面头部,而 `excerpt` 并不会被渲染到页面,`date`被渲染在页面底部。 112 | 113 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661781216174.png) 114 | 115 | 下面是一个较完整的文档例子,其标题是 Java , 描述是 Java Note, 创建日期是 2020-8-25,主要内容是从 `# Java` 开始的下面那些内容: 116 | 117 | ```md 118 | --- 119 | title: Java 120 | excerpt: Java Note 121 | date: 2022-8-25 122 | --- 123 | 124 | ## Java 125 | Java 是由 Sun Microsystems 公司于 1995 年 5 月推出的高级程序设计语言。 126 | Java 可运行于多个平台,如 Windows, Mac OS 及其他多种 UNIX 版本的系统。 127 | 本教程通过简单的实例将让大家更好的了解 Java 编程语言。 128 | 移动操作系统 Android 大部分的代码采用 Java 编程语言编程。 129 | 130 | 131 | 132 | ## Java Examples 133 | 134 | 以上我们使用了两个命令 javac 和 java。 135 | javac 后面跟着的是java文件的文件名,例如 HelloWorld.java。 该命令用于将 java 源文件编译为 class 字节码文件,如: javac HelloWorld.java。 136 | 运行javac命令后,如果成功编译没有错误的话,会出现一个 HelloWorld.class 的文件。 137 | java 后面跟着的是java文件中的类名,例如 HelloWorld 就是类名,如: java HelloWorld。 138 | ``` 139 | 140 | 当你完成一篇内容的编辑后,进行保存, Daymd 会自动解析你的文档内容并生成静态页面,上面的文档解析结果如下,文档使用的 Markdown 语法特性将在后面的章节中讲述。 141 | 142 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220830102220.png) 143 | 144 | <Tips title="遇到问题?">如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 issue 提交界面.</Tips><To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 145 | -------------------------------------------------------------------------------- /content/docs/001-docandblog/001-poststruct.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 博客结构 3 | excerpt: 博客的结构 4 | date: 2022-08-29 5 | --- 6 | 7 | 在本节中,我们将阐述 Daymd 中博客的结构。以便让你清楚创建什么样的结构能够在网站上展示什么样的结果。 8 | 9 | ## 博客的基本结构 10 | 11 | 博客与文档不同,博客是每一篇独立存在的,不存在集合关系,因此你只能创建单个博客,而不能创建**集合**,正如下面的博客页面所示: 12 | 13 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220830102543.png) 14 | 15 | 左侧是博客列表,它按照从新到旧的顺序展示。点击即可进入相应的博客页面。在文件结构中,所有的博客均放在 `content/posts` 文件夹下,除博客首页文件 `index.mdx` 外,每篇博客都有单独的文件夹,以及这篇博客的页面文件 `index.mdx` 。 16 | 17 | ## 创建博客 18 | 19 | 现在,我们在 posts 文件夹上右键创建新的文件夹。 20 | 21 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220830121504.png) 22 | 23 | <Note title="命名规则"> 24 | 在为博客文件夹命名时,请按照 `yyyy-MM-dd-blogName` 的格式进行命名。Daymd会按照时间为你排序。 25 | </Note> 26 | 27 | 将其命名为 `2022-8-30-myfirstblog` 然后在这个文件夹中添加页面 `index.mdx` 。为这个文件添加内容。 28 | 29 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661842553336.png) 30 | 31 | ```md 32 | --- 33 | title: 博客结构 34 | excerpt: 博客的结构 35 | date: 2022-08-29 36 | backpic: null 37 | --- 38 | ## 一个博客标题 39 | 这是这个标题下的内容。 40 | ``` 41 | 42 | 按下 `ctrl`+`s` 保存文件,可以看到右边的执行窗口开始刷新,等待刷新完成。 43 | 刷新完成后,如下: 44 | 45 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220830145113.png) 46 | 47 | 你的博客区成功创建了一片新的博客。但是请注意,**不要**在每篇博客文件夹中再创建其他 `markdown` 文件,否则会引发错误。 48 | 恭喜!现在你按照上面的步骤就可以多篇自己的博客了。 49 | 50 | ## 编写一篇博客 51 | 52 | 像文档一样,我们现在来编写一篇博客。同样地,它也由**格式头**和**内容**组成。博客的格式头相较于文档增加了 `backpic` 字段,它用来在首页展示博客列表时显示背景图片。 53 | 54 | ### 无背景模式 55 | 56 | 在无背景模式下将 `backpic` 字段填写为 `null`。 57 | 58 | ```md 59 | --- 60 | title: 博客标题 61 | excerpt: 博客的描述 62 | date: 2022-08-29 # 博客创建时间 63 | backpic: null # 博客列表背景图片 64 | --- 65 | ``` 66 | 67 | ### 有背景模式 68 | 69 | 在有背景模式下将 `backpic` 字段填写为图床链接。在后面的章节我们将介绍图床的使用。 70 | 71 | ```md 72 | --- 73 | title: 博客标题 74 | excerpt: 博客的描述 75 | date: 2022-08-29 # 博客创建时间 76 | backpic: url(https://api.maho.cc/random-img/pc.php) # 博客列表背景图片 77 | --- 78 | ``` 79 | 80 | <Warn> 81 | 请注意,背景图片的格式为 `backpic:url(链接)`,而不是 `backpic:链接`。`url` 以及后面的括号是必须的。否则不会生效。 82 | </Warn> 83 | 84 | ### 例子 85 | 86 | 下面是一个较完整的博客例子,其标题是 Java , 描述是 Java Note, 创建日期是 2020-8-25,背景图链接为 `https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/NavBanner.png` 主要内容是从 `# Java` 开始的下面那些内容: 87 | 88 | ```md 89 | --- 90 | title: Java 91 | excerpt: Java Note 92 | date: 2022-8-25 93 | backpic: https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/NavBanner.png 94 | --- 95 | 96 | ## Java 97 | Java 是由 Sun Microsystems 公司于 1995 年 5 月推出的高级程序设计语言。 98 | Java 可运行于多个平台,如 Windows, Mac OS 及其他多种 UNIX 版本的系统。 99 | 本教程通过简单的实例将让大家更好的了解 Java 编程语言。 100 | 移动操作系统 Android 大部分的代码采用 Java 编程语言编程。 101 | 102 | 103 | 104 | ## Java Examples 105 | 106 | 以上我们使用了两个命令 javac 和 java。 107 | javac 后面跟着的是java文件的文件名,例如 HelloWorld.java。 该命令用于将 java 源文件编译为 class 字节码文件,如: javac HelloWorld.java。 108 | 运行javac命令后,如果成功编译没有错误的话,会出现一个 HelloWorld.class 的文件。 109 | java 后面跟着的是java文件中的类名,例如 HelloWorld 就是类名,如: java HelloWorld。 110 | ``` 111 | 112 | <Tips title="遇到问题?">如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 issue 提交界面.</Tips><To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 113 | -------------------------------------------------------------------------------- /content/docs/001-docandblog/index.zh.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 文档和博文 3 | excerpt: 书写文档和博客文章 4 | date: 2022-08-29 5 | --- 6 | 7 | ## 主要内容 8 | 9 | 在这一章节,我们将了解 Markdown 的语法,以及告诉大家如何写好**文档**和**博文**,并阐述 Daymd 带给你的一些 Markdown 特性。Daymd 的主要目的就是构建以文档为中心的网站,在这一块中会很强烈突出**文档**的特点。 10 | 11 | ## 文档 12 | 13 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220830150125.png) 14 | 15 | ## 博客 16 | 17 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220830150203.png) 18 | 19 | <Tips title="遇到问题?">如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 issue 提交界面.</Tips><To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 20 | -------------------------------------------------------------------------------- /content/docs/002-markdowntext/001-headings.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 标题和目录 3 | excerpt: 标题和目录 4 | date: 2022-08-30 5 | --- 6 | 7 | 标题是一篇文章的分层标志,Markdown 文章中将使用 `#` 的数量描述标题的深度: 8 | 9 | ```md title="index.md" 10 | --- 11 | // 格式头 12 | --- 13 | 14 | # 文章副标题 15 | 16 | ## 章节标题 17 | 18 | ### 节标题 19 | 20 | #### 段落标题 21 | ``` 22 | 23 | 上面的 Markdown 内容将展示如下: 24 | 25 | --- 26 | 27 | # 文章副标题 28 | 29 | ## 章节标题 30 | 31 | ### 节标题 32 | 33 | #### 段落标题 34 | 35 | --- 36 | 37 | 使用相应的标题后,章节标题和节标题会自动在右侧生成目录。 38 | 39 | ## 试一试 40 | 41 | 现在,新建一篇博客或者文档,在里面书写下面的内容: 42 | 43 | ```md 44 | --- 45 | title: 博客结构 46 | excerpt: 博客的结构 47 | date: 2022-08-29 48 | backpic: null 49 | --- 50 | 51 | ## 一、第一章 52 | 53 | ### 1.1 第一章第一节 54 | 55 | 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容 56 | 57 | ### 1.2 第一章第二节 58 | 59 | 内容内容内容内容内容内容内容内容内容内容内容内容内容 60 | 61 | ## 二、第二章 62 | 63 | ### 2.1 第二章第一节 64 | 65 | 内容内容内容内容内容内容内容内容内容内容内容内容内容 66 | 67 | ### 2.2 第二章第二节 68 | 69 | 内容内容内容内容内容内容内容内容内容内容内容内容内容 70 | 71 | #### 小标题 72 | ``` 73 | 74 | 它将展示: 75 | 76 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220830152608.png) 77 | 78 | <Tips title="遇到问题?"> 79 | 如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 80 | issue 提交界面. 81 | <To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 82 | </Tips> 83 | -------------------------------------------------------------------------------- /content/docs/002-markdowntext/002-boldthing.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 修饰和强调 3 | excerpt: 修饰和强调 4 | date: 2022-08-30 5 | --- 6 | 7 | ## 文字加粗 8 | 9 | 你可以使用`**` 来指定文字加粗。使用方法是使用 `**` 来包裹一个你想加粗的文本。 10 | 11 | ```md 12 | **这是加粗的文本**。 13 | ``` 14 | 15 | 显示效果: 16 | 17 | **这是加粗的文本**。 18 | 19 | ## 文字倾斜 20 | 21 | 你可以使用`*` 来指定文字倾斜。使用方法是使用 `*` 来包裹一个你想倾斜的文本。 22 | 23 | ```md 24 | *这是倾斜的文本* 25 | ``` 26 | 27 | 显示效果: 28 | 29 | *这是倾斜的文本* 30 | 31 | ## 同时使用粗体和斜体 32 | 33 | 你可以同时使用 `*` `**` 来指定文字倾斜。使用方法是使用 `***` 来包裹一个你想倾斜的文本。 34 | 35 | ```md 36 | ***这是倾斜且加粗的文本*** 37 | ``` 38 | 39 | 显示效果: 40 | 41 | ***这是倾斜且加粗的文本*** 42 | 43 | ## 换行 44 | 45 | 请在每行文字的末尾输入两个**空格** 进行换行。 46 | 47 | ```md 48 | 这是一行文字 #这一行的末尾没有两个空格 49 | 这时下一行文字 50 | ``` 51 | 52 | **显示效果:** 53 | 54 | 这是一行文字 55 | 这时下一行文字 (并没有换行) 56 | 57 | ```md 58 | 这是一行文字 #这一行的末尾有两个空格 59 | 这时下一行文字 60 | ``` 61 | 62 | **显示效果:** 63 | 64 | 这是一行文字 65 | 这时下一行文字 66 | 67 | ## 引用 68 | 69 | 使用 `>` 就可以指定文字为引用。 70 | 71 | ```md 72 | > 这是一个引用 73 | ``` 74 | 75 | **显示效果:** 76 | > 这是一个引用 77 | 78 | 在引用中可以叠加其他的语法。 79 | 80 | ```md 81 | > ### 在应用中的标题 82 | > 在引用中的**加粗** 83 | ``` 84 | 85 | **显示效果:** 86 | 87 | > ### 在引用中的标题 88 | 89 | > 在引用中的**加粗** 90 | 91 | ## 列表 92 | 93 | ```md 94 | 1. First item 95 | 2. Second item 96 | 3. Third item 97 | 4. Fourth item 98 | ``` 99 | 100 | 显示效果: 101 | 102 | 1. First item 103 | 2. Second item 104 | 3. Third item 105 | 4. Fourth item 106 | 107 | 也可以使用 `-` 来指定列表。 108 | 109 | ```md 110 | - First item 111 | - Second item 112 | - Third item 113 | - Fourth item 114 | ``` 115 | 116 | 为了避免 `1.` 等格式被渲染为小圆点,可以略去 `1.` 后面的空格,但是记得在每行后面添加两个空格换行。 117 | 118 | ```md 119 | 1.First item 120 | 2.Second item 121 | 3.Third item 122 | 4.Fourth item 123 | ``` 124 | 125 | 你将看到被原封不动渲染出来: 126 | 127 | 1.First item 128 | 2.Second item 129 | 3.Third item 130 | 4.Fourth item 131 | 132 | ## 小代码块 133 | 134 | 你可以使用 **``** 来指定一段小代码。这之中的内容不会被解析成 Markdown元素。 135 | 136 | ```md 137 | `<div>Hello World</div>` 138 | ``` 139 | 140 | **显示效果**: 141 | 142 | `<div>Hello World</div>` 143 | 144 | 如果你在你的文章中使用 HTML 语法却不使用 `` 进行包裹,会发生报错。 145 | 146 | ## 分割线 147 | 148 | 要创建分隔线,请在单独一行上使用三个或多个星号 `***`、破折号 `---` 或下划线 `___` ,并且不能包含其他内容。 149 | 150 | ```md 151 | *** 152 | 153 | --- 154 | 155 | _________________ 156 | ``` 157 | 158 | 显示效果: 159 | 160 | *** 161 | 162 | --- 163 | 164 | _________________ 165 | 166 | <Tips title="遇到问题?">如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 issue 提交界面.</Tips><To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 167 | -------------------------------------------------------------------------------- /content/docs/002-markdowntext/003-codinglang.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 代码块 3 | excerpt: 代码块 4 | date: 2022-08-30 5 | --- 6 | 7 | 我们为您提供了代码块语法,让你能够在你的文章中展示大段的代码块。 8 | 9 | ## 无标题代码块 10 | 11 | 你可以使用下面的格式进行展示: 12 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220830155953.png) 13 | 显示效果: 14 | 15 | ```java 16 | public class HelloWorld { 17 | public static void main(String[] args) { 18 | System.out.println("Hello World!"); 19 | } 20 | } 21 | ``` 22 | 23 | 即在连续三个反引号之后书写代码的语言比如 `java` `js` `c` `html` `css`等。然后再使用连续三个反引号结束。 24 | 25 | ## 有标题代码块 26 | 27 | 使用 `title="代码块标题"` 指定代码块标题。 28 | 29 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220830160321.png) 30 | 31 | ```java title="代码块标题" 32 | public class HelloWorld { 33 | public static void main(String[] args) { 34 | System.out.println("Hello World!"); 35 | } 36 | } 37 | ``` 38 | 39 | <Tips title="遇到问题?"> 40 | 如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 41 | issue 提交界面. 42 | <To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 43 | </Tips> 44 | -------------------------------------------------------------------------------- /content/docs/002-markdowntext/004-notice.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 告示条 3 | excerpt: 告示条 4 | date: 2022-08-30 5 | --- 6 | 7 | 我们为您提供了**告示条**语法,你可以在您的项目中使用它。 8 | 9 | ## 提示 10 | 11 | ### 有标题提示 12 | 13 | ```md 14 | <Tips title="标题">这里面填写内容。</Tips> 15 | ``` 16 | 17 | <Tips title="标题">这里面填写内容。</Tips> 18 | 19 | ### 无标题提示 20 | 21 | ```md 22 | <Tips>这里面填写内容。</Tips> 23 | ``` 24 | 25 | <Tips>这里面填写内容。</Tips> 26 | 27 | ## 警告 28 | 29 | ### 有标题警告 30 | 31 | ```md 32 | <Warn title="标题">这里面填写内容。</Warn> 33 | ``` 34 | 35 | <Warn title="标题">这里面填写内容。</Warn> 36 | 37 | ### 无标题警告 38 | 39 | ```md 40 | <Warn>这里面填写内容。</Warn> 41 | ``` 42 | 43 | <Warn>这里面填写内容。</Warn> 44 | 45 | ## 笔记 46 | 47 | ### 有标题笔记 48 | 49 | ```md 50 | <Note title="标题">这里面填写内容。</Note> 51 | ``` 52 | 53 | <Note title="标题">这里面填写内容。</Note> 54 | 55 | ### 无标题笔记 56 | 57 | ```md 58 | <Note>这里面填写内容。</Note> 59 | ``` 60 | 61 | <Note>这里面填写内容。</Note> 62 | 63 | ## 危险 64 | 65 | ### 有标题危险 66 | 67 | ```md 68 | <Danger title="标题">这里面填写内容。</Danger> 69 | ``` 70 | 71 | <Danger title="标题">这里面填写内容。</Danger> 72 | 73 | ### 无标题危险 74 | 75 | ```md 76 | <Danger>这里面填写内容。</Danger> 77 | ``` 78 | 79 | <Danger>这里面填写内容。</Danger> 80 | 81 | ## 举例 82 | 83 | ### 有标题举例 84 | 85 | ```md 86 | <Example title="标题">这里面填写内容。</Example> 87 | ``` 88 | 89 | <Example title="标题">这里面填写内容。</Example> 90 | 91 | ### 无标题举例 92 | 93 | ```md 94 | <Example>这里面填写内容。</Example> 95 | ``` 96 | 97 | <Example>这里面填写内容。</Example> 98 | 99 | <Tips title="遇到问题?"> 100 | 如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 101 | issue 提交界面. 102 | <To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 103 | </Tips> 104 | -------------------------------------------------------------------------------- /content/docs/002-markdowntext/005-linkings.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 链接 3 | excerpt: 链接 4 | date: 2022-08-30 5 | --- 6 | 7 | 我们为您提供了两种链接跳转语法。 8 | 9 | ## 原生链接 10 | 11 | 使用 Markdown 链接,请使用 `[text](url)` 格式。其中 text 用于描述链接标题,url 用于指定链接地址。 12 | 13 | ```md 14 | [bing搜索](https://www.bing.com/) 15 | ``` 16 | 17 | 效果: 18 | 19 | [bing搜索](https://www.bing.com/) 20 | 21 | ## To 链接 22 | 23 | 这是 Daymd 为您提供的链接方式。它支持内部跳转和外部跳转。 24 | 25 | ### 外部跳转 26 | 27 | ```md 28 | <To to="https://www.bing.com/"> bing 搜索 </To> 29 | ``` 30 | 31 | <To to="https://www.bing.com/"> bing 搜索 </To> 32 | 33 | ### 内部跳转 34 | 35 | 内部跳转时只能跳转到已经存在的 Next.js 路由,你可以在浏览器导航栏中得到它。 36 | 37 | ```bash 38 | http://localhost:3001/zh/docs/fastgo/preparation 39 | ``` 40 | 41 | 例如在浏览器导航栏中得到上面的链接,那么 `http://localhost:3001/zh` 之后的内容 `/docs/fastgo/preparation`就是内部路由,可以填写在 `to` 属性中。 42 | 43 | ```md 44 | <To to="/posts"> 博客首页 </To> 45 | ``` 46 | 47 | <To to="/posts"> 博客首页 </To> 48 | 49 | 又或者跳转到某篇具体的文章: 50 | 51 | ```md 52 | <To to="/docs/fastgo/preparation"> 准备工作 </To> 53 | ``` 54 | 55 | <To to="/docs/fastgo/preparation"> 准备工作 </To> 56 | 57 | <Tips title="进阶内容"> 58 | 同时,`To`标签还接受参数 `className` ,用于指定跳转按钮的样式。建议使用 Tailwind 语法,如: 59 | 60 | ```md 61 | <To to="/docs/fastgo/preparation" className="bg-opacity-25"> 准备工作 </To> 62 | ``` 63 | 64 | <To to="/docs/fastgo/preparation" className="bg-opacity-25"> 准备工作 </To> 65 | 66 | 又或者,你可以为其添加自定义类名,如: 67 | 68 | ```md 69 | <To to="/docs/fastgo/preparation" className="my-btn-style"> 准备工作 </To> 70 | ``` 71 | 72 | 然后在 `styles/global.css` 文件中添加如下代码: 73 | 74 | ```css 75 | .my-btn-style { 76 | background-color: #dd68edee !important; 77 | box-shadow: none !important; 78 | border: 2px soild #d43111 !important; 79 | transition: all 2s ease-in-out !important; 80 | height: 100px !important; 81 | margin-bottom: 10px; 82 | } 83 | ``` 84 | 85 | 就可以自定义按钮样式了。 86 | 87 | <To to="/docs/fastgo/preparation" className="my-btn-style"> 准备工作 </To> 88 | 89 | 注意,请记得添加 `!important`,否则可能会导致样式无法生效。 90 | 91 | </Tips> 92 | 93 | <Tips title="遇到问题?">如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 issue 提交界面.</Tips><To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 94 | -------------------------------------------------------------------------------- /content/docs/002-markdowntext/006-pictures.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 图片 3 | excerpt: 图片 4 | date: 2022-08-30 5 | --- 6 | ## 语法 7 | 8 | 我们允许你在文章中使用图片,但是需要注意的是,这些图片不是在 Markdown 文件中。而是用链接的形式引入。 9 | 10 | ```md 11 | ![image.png](https://source.unsplash.com/1600x900/?nature,water) 12 | ``` 13 | 14 | 显示效果: 15 | 16 | ![image.png](https://source.unsplash.com/1600x900/?nature,water) 17 | 18 | ## 图床使用 19 | 20 | 假如把图片放在工程本地,将会导致打包大小变得很大,并且托管到 Vercel 或者 Netlify 后图片加载的速度惨不忍睹。因此我们建议建立图床,使用外链引入到Markdown笔记中,这样工程包的大小缩小了,访问速度也有所提升。 21 | 22 | ### 图床推荐 23 | 24 | [imgse](https://imgse.com/) 25 | [superbed](https://www.superbed.cn/) 26 | [薄荷图床](https://riyugo.com/) 27 | [云图床](https://cloudimge.com/) 28 | 29 | 此外还有微博图床或者自己搭建图床,下面将讲解微博图床搭建方法以及阿里云图床搭建方法。 30 | 31 | ## 微博图床 32 | 33 | ### 安装微博图床插件 34 | 35 | 点击[微博图床插件](https://chrome.google.com/webstore/detail/%E5%BE%AE%E5%8D%9A%E5%9B%BE%E5%BA%8A/pinjkilghdfhnkibhcangnpmcpdpmehk)进行下载安装(需要科学上网) 36 | 37 | ### 打开微博图床插件 38 | 39 | ![image.png](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/img/006SHRs9gy1h2x8b859utj316u0op45r.jpg) 40 | 41 | 它可能需要你登录微博,那么访问微博就好了。 42 | 使用非常的便捷,只要将需要的图片复制进入窗口即可。 43 | 如图,你只需要上传一张图片,然后在窗口中粘贴即可。右边会生成各种代码,你可以直接将 Markdown 链接粘贴到你的工程中。 44 | 45 | ![image.png](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/img/006SHRs9gy1h2x8crjlfij30r40isjx3.jpg) 46 | 47 | ```html 48 | <img src="https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/img/006SHRs9gy1h2x8crjlfij30r40isjx3.jpg"/> 49 | ``` 50 | 51 | 在你的博客中,像下面这样插入图片: 52 | 53 | ```markdown 54 | ![image.png](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/img/006SHRs9gy1h2x8crjlfij30r40isjx3.jpg) 55 | ``` 56 | 57 | <Danger> 58 | 首先感谢新浪微博提供的免费图床(对外链无限制),以及速度快到惊人的cdn图片加速服务,还有丰富的浏览器插件,简直是薅羊毛!但是,由于这个图床服务并不是微博官方提供给用户的服务,所以,一旦微博停止这个服务,我们的**图片将无法访问**,有一种“命运攥在别人手里”的感觉。所有免费图床都有这个缺点!!所以建议要么做好备份,要么自己搭建图床。 59 | </Danger> 60 | 61 | ## 阿里云OSS 62 | 63 | ### 注册 64 | 65 | 首先,在阿里云首页选择对象存储OSS服务。 66 | ![1.png](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1656914971349.png) 67 | 68 | *** 69 | 70 | ### 创建bucket 71 | 72 | 点击创建一个新的bucket。 73 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220704141214.png) 74 | 填写bucket参数。 75 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220704141354.png) 76 | *** 77 | 78 | ### 获取地域结点信息 79 | 80 | 打开创建的bucket列表,如图,只需要复制oss-cn-beijing即可,不需要后面的.aliyuncs.com。 81 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220704142346.png) 82 | *** 83 | 84 | ### 创建AccessKey 85 | 86 | 来到页面的右上角,鼠标放在你的头像上,在弹出的框里选择AccessKey管理。 87 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220704142626.png) 88 | 进入后,创建一个`AccessKey`。 89 | ![4](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220704142811.png) 90 | 在弹出的界面里,记住你的accessKeyId和accessKeySecret. 91 | 92 | ## PicGo 93 | 94 | ### 配置 95 | 96 | 在Github中下载[PicGo](https://github.com/Molunerfinn/PicGo/releases),并点击安装。在电脑桌面右下角的PicGo图标打开软件。在图床设置里面选择阿里云OSS,依照以下步骤填写信息: 97 | 98 | 1. 设定`Keyld`:填写刚刚获得的AccessKeyID 99 | 100 | 2. 设定`KeySecret`:填写AccessKeyIDSecret 101 | 102 | 3. 设定储存空间名:填写`bucket`名称,这里填写的是bucket名称,不是浏览器里的域名。 103 | 104 | 4. 确认存储区域:填写你的地域节点,注意复制的格式。 105 | 106 | 5. 指定存储路径:其实就是自定义一个文件夹的名字,以/结尾,它会自动在你的bucket里面创建一个文件夹,并把图片上传进去。 107 | 108 | ![3](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220704143542.png) 109 | 110 | ### 使用 111 | 112 | 使用时,Picgo和其他图床一样,只需要把图片拖到图床上即可。 113 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220830165007.png) 114 | 你可以登录你的阿里云OSS,查看你的图片。 115 | 116 | <Tips>每年9元实际上并不贵,可以放心使用</Tips> 117 | 118 | <Tips title="遇到问题?">如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 issue 提交界面.</Tips><To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 119 | -------------------------------------------------------------------------------- /content/docs/002-markdowntext/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Markdown 特性 3 | excerpt: markdown 特性 4 | date: 2022-08-30 5 | --- 6 | 7 | ## Markdown 8 | 9 | Markdown 是一种**轻量级**的**标记语言**,可用于在纯文本文档中添加**格式化元素**。 10 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220829204141.png) 11 | 它专注于文字内容,用纯文本的形式存储,易读易写,语法简单,没有什么学习成本,能轻松在码字的同时做出美观大方的排版。使用 Markdown 与使用 Word 等编辑器不同。在 Word 之类的应用程序中,可以点击 Word 提供的各种功能进行排版,并且,更改立即可见。而 Markdown 与此不同,当你创建 Markdown 格式的文件时,可以在文本中添加 Markdown 语法,以指示哪些单词和短语看起来应该有所不同。 12 | 13 | 例如,要表示标题,只须在短语前面添加一个井号即可(例如,`# Heading One`)。或者要加粗一个短语,只须在短语前后各加两个星号即可(例如,`**this text is bold**`)。 14 | 15 | 在这一章节,我们会聚焦于 Markdown 的特性,讲述怎么快速方便的搭建高度精华的博客和文档。 16 | 17 | <Tips title="遇到问题?">如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 issue 提交界面.</Tips><To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 18 | -------------------------------------------------------------------------------- /content/docs/003-api/000-themes.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 主题预览 3 | excerpt: 主题预览 4 | date: 2022-08-31 5 | --- 6 | 7 | 我们为您提供了 29 种主题,您可以在下面进行点击体验,选择您心怡的主题后,将其**名称变为小写字母**添加到 `daymd.config.js` 中的 `themeSelect` 选项。 8 | 9 | 不同的主题将影响: 10 | 11 | - 字体 12 | - 配色 13 | - UI 样式(卡片、按钮等) 14 | 15 | <ThemeChange></ThemeChange> 16 | 17 | <Tips title="遇到问题?"> 18 | 如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 19 | issue 提交界面. 20 | <To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 21 | </Tips> 22 | -------------------------------------------------------------------------------- /content/docs/003-api/001-navsetting.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 导航页面 3 | excerpt: 导航页面 4 | date: 2022-08-31 5 | --- 6 | 7 | Daymd 为您提供了个人导航库。您可以在里面收藏自己喜爱的站点。 8 | 9 | ## 启用 10 | 11 | 在 API 中设置 `navItems` 中添加一条 Nav 的数据,或者在页脚中添加 Nav 的数据。 12 | 13 | ```js 14 | navItems: [ 15 | // ... 16 | { 17 | name: 'Nav', 18 | to: '/website', 19 | }, 20 | // ...可以继续添加 21 | ], 22 | ``` 23 | 24 | ## 数据添加 25 | 26 | 导航页面有**独立的**数据管理页面,您可以在这里添加数据。目标文件夹是 `/navData`。 27 | 28 | ### 友链 29 | 30 | 打开文件 `navData/friend.ts` 在里面添加友链数据。 31 | 32 | 示例数据: 33 | 34 | ```js 35 | export const Friends: Friend[] = [ 36 | { 37 | title: "Jetzihan", 38 | description: "Daymd 作者的个人网站", 39 | website: "https://jetzihan.netlify.app/", 40 | avatar: "https://avatars.githubusercontent.com/u/83146544?v=4", 41 | }, 42 | { 43 | title: "小张的博客", 44 | description: "小张的个人网站", 45 | website: "https://example.com", 46 | avatar: "https://avatars.githubusercontent.com/u/83146544?v=4", 47 | }, 48 | // ... 49 | ]; 50 | ``` 51 | 52 | 方括号中可以包含无数条数据,每条数据都是一个 Friend 类型的对象。每条数据包含四个字段, 分别是:`title`, `description`, `website`, `avatar`。分别用来指明站点名称、描述、站点地址、头像地址。 53 | 54 | ### 站点收藏 55 | 56 | 打开文件 `navData/website.ts` 在里面添加站点数据。它可以被分成各个类别,各个类别为一条数据,你可以在 `WebsiteCategory` 后面的方括号中添加数据。 57 | 58 | ```js 59 | export const websiteData: WebsiteCategory[] = [ 60 | // ... 61 | { 62 | name: "工具", 63 | websites: [ 64 | { 65 | name: "CodePen", 66 | desc: "前端创意大本营", 67 | logo: "https://cpwebassets.codepen.io/assets/favicon/favicon-aec34940fbc1a6e787974dcd360f2c6b63348d4b1f4e06c77743096d55480f33.ico", 68 | href: "https://codepen.io/", 69 | tags: ["在线编码", "开发平台"], 70 | }, 71 | { 72 | name: "Codesandbox", 73 | desc: "在线编码代码沙盒", 74 | logo: "https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220806212946.png", 75 | href: "https://codesandbox.io/?from-app=1", 76 | tags: ["在线编码", "开发平台"], 77 | }, 78 | { 79 | name: "stackblitz", 80 | desc: "针对 Web 开发者的在线 IDE", 81 | logo: "https://c.staticblitz.com/assets/pwa-icon-f559737e5eae9b3544e5cc1291118bf758ee20873d496f1ce2052859fb3b72d6.png", 82 | href: "https://stackblitz.com/", 83 | tags: ["在线编码", "开发平台"], 84 | }, 85 | ], 86 | }, 87 | // .... 88 | ] 89 | ``` 90 | 91 | 以上是一个类别的示例,每个类别包含两个字段,分别是 `name` 和 `websites`。`name` 是类别的名称,`websites` 是一个数组,包含了类别下的站点数据。每个站点数据又包含五个字段,分别是 `name`, `desc`, `logo`, `href`, `tags`。分别用于指明站点的名称、描述、站点的 logo 地址、站点的地址、站点的标签。 92 | 93 | ```js 94 | { 95 | name: "stackblitz", 96 | desc: "针对 Web 开发者的在线 IDE", 97 | logo: "https://c.staticblitz.com/assets/pwa-icon-f559737e5eae9b3544e5cc1291118bf758ee20873d496f1ce2052859fb3b72d6.png", 98 | href: "https://stackblitz.com/", 99 | tags: ["在线编码", "开发平台"], 100 | }, 101 | ``` 102 | 103 | 上述**工具**类别的数据渲染成果如下: 104 | 105 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220831100359.png) 106 | 107 | <Tips title="遇到问题?">如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 issue 提交界面.</Tips><To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 108 | -------------------------------------------------------------------------------- /content/docs/004-build/000-saveit.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 保存和提交项目 3 | excerpt: 保存和提交项目 4 | date: 2022-08-30 5 | --- 6 | 7 | <Warn>在编辑器预览时往往运行较迟钝,但是打包后就不会有这个问题,这是正常现象。</Warn> 8 | 9 | 当你在 StackBlitz 中或者在本地 Visual Studio Code 完成你的项目的编辑后,你可以按住 `ctrl` `s` 或者 `⌘` `s` 来保存项目。然后,你就可以将代码提交回 GitHub 了。 10 | 11 | ## StackBlitz 12 | 13 | 在项目左上角点击 `commit` 按钮按照提示点击 `commit` 。现在,你更新的代码就保存到 GitHub 了。 14 | 15 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661912742628.png) 16 | 17 | 出现最近更新的时间。表明提交成功: 18 | 19 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661912963333.png) 20 | 21 | ## 本地提交 22 | 23 | 本地提交不再赘述,通过 Git 工具提交即可。 24 | 25 | <Tips title="遇到问题?">如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 issue 提交界面.</Tips><To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 26 | -------------------------------------------------------------------------------- /content/docs/004-build/001-netlify.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Netlify 3 | excerpt: Netlify 4 | date: 2022-08-31 5 | --- 6 | ## 介绍 7 | 8 | Netlify 是一个提供网站部署服务的开源平台,可以让开发者在线部署静态网站。仅仅需要几部简单的操作就可以完成一个网站的部署与发布。 9 | 10 | ## 登录 11 | 12 | 进入 <To to="https://www.netlify.com/">Netlify</To> 网站,点击右上角 `Sign Up` 进行登录。 13 | 14 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661913403135.png) 15 | 16 | <Warn>注意,必须使用 GitHub 进行登录。</Warn> 17 | 18 | ## 导入仓库 19 | 20 | 注册完成后,进入控制台界面,选择 `Add a new site`,创建一个新的项目。 21 | 22 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661913530253.png) 23 | 24 | 选择 `Import an existing project from a Git repository` 然后选择 GitHub 导入: 25 | 26 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661913574817.png) 27 | 28 | 选择目标仓库(你 Fork 的仓库)。 29 | 30 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661913643644.png) 31 | 32 | ## 部署 33 | 34 | 选择部署分支为 `main` 取决于你存放的分支。 35 | 36 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220831104147.png) 37 | 38 | 下面的选项是部署指令,不用理会。它已经帮我们选好了。 39 | 40 | 点击 `Deploy Site` 即可完成搭建。 41 | 42 | 点击进入可以看到部署过程。 43 | 44 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661913831131.png) 45 | 46 | 出现 `Site is live` 即部署完成。 47 | 48 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661913972393.png) 49 | 50 | ## 部署设置 51 | 52 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661914043398.png) 53 | 54 | 点击进入站点设置,为项目更改名字。 55 | 56 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661914091082.png) 57 | 58 | ![3](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661914130745.png) 59 | 60 | 修改成功。 61 | 62 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220831104929.png) 63 | 64 | 访问这个链接。 65 | 66 | ![3](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661914227371.png) 67 | 68 | 访问得到预期成果,部署完成! 69 | 70 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220831105116.png) 71 | 72 | 之后,你对你的博客进行修改,增加文章等操作,一旦 GitHub 内容发生变化, Netlify 会自动帮你进行重新部署,待一段时间后即可重新看到。 73 | 74 | <Tips title="遇到问题?">如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 issue 提交界面.</Tips><To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 75 | -------------------------------------------------------------------------------- /content/docs/004-build/002-vercel.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Vercel 3 | excerpt: Vercel 4 | date: 2022-08-31 5 | --- 6 | 7 | ## 介绍 8 | 9 | Vercel 是一个 Web 应用部署工具,支持部署静态网页和Node服务,部署后你还可以访问它自带生成的域名https。 10 | 11 | ## Vercel 部署 12 | 13 | 打开[Vercel 登录](https://vercel.com/login),选择使用 Github 登录。 14 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220725145225.png) 15 | 16 | 然后选择新建项目: 17 | 18 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661914989167.png) 19 | 20 | 选择你 Fork 的 Daymd 项目: 21 | 22 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1661915066184.png) 23 | 24 | 你可以忽略 **Create a Team (Optional)** ,看下面的: 25 | 26 | ![3](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220831110505.png) 27 | 28 | 显然,它已经帮我们识别了我们的项目,要干什么它已经帮我们设置好了。 29 | 那就不用管了,点击 **Deploy**。 30 | 31 | ![2](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220831110552.png) 32 | 33 | 等待部署完成。 34 | 35 | ![5](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220831110726.png) 36 | 37 | 很有仪式感的界面。 38 | 点击 `Go to Dashboard`,进入管理界面。然后点击展示域名设置。 39 | ![7](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1658732581412.png) 40 | 然后创建一个形如 `xxxx.vercel.app` 的域名。 41 | ![8](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220725150427.png) 42 | OK!选择 ADD,之后你就可以在这个域名看到你的博客啦! 43 | ![9](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220725150523.png) 44 | ![11](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/1658732793550.png) 45 | 46 | 之后,你对你的博客进行修改,增加文章等操作,一旦 GitHub 内容发生变化, Vercel 会自动帮你进行重新部署,待一段时间后即可重新看到。 47 | 48 | <Danger>近期,由于某些原因,`vercel.app` 被 DNS 污染,在国内已经打不开了,需要使用 Ladder ,因此建议不要使用 Vercel 部署了,最好选用 Netlify。</Danger> 49 | 50 | 另外,还有其他的部署方式,如 `Github Pages` 和 `腾讯的 Weblify` ,感兴趣可以自己去研究。 51 | 52 | <Tips title="遇到问题?">如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 issue 提交界面.</Tips><To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 53 | -------------------------------------------------------------------------------- /content/docs/004-build/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 部署和发布 3 | excerpt: 部署和发布 4 | date: 2022-08-30 5 | --- 6 | 7 | 经过上面的一系列操作,我们已经完成了自己的博客项目,现在我们需要将它**部署到一个服务器**,并用一个**域名**来访问它。 8 | 9 | <Tips title="别怕!">你可能听到服务器,就觉得非常困难了。但是并不是这样的,我们可以使用一些自动部署托管工具帮我们完成这项工作。</Tips> 10 | 11 | 我们可能会用到下面两个工具的其中之一,你只要选择其中一种部署即可: 12 | 13 | ## Netlify 14 | 15 | **免费**。 16 | 17 | <To to="https://www.netlify.com/">Netlify</To> 18 | 19 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220831101222.png) 20 | 21 | ## Vercel 22 | 23 | **免费**。 24 | 25 | <To to="https://vercel.com/home">Vercel</To> 26 | 27 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220831101559.png) 28 | 29 | <Tips title="遇到问题?">如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 issue 提交界面.</Tips><To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 30 | -------------------------------------------------------------------------------- /content/docs/005-improve/000-newpages.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 页面创建 3 | excerpt: 页面创建 4 | date: 2022-08-31 5 | --- 6 | 7 | ## React介绍 8 | 9 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220831132731.png) 10 | 11 | React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站。它有**声明式**、**高效**、**灵活**的特点。 12 | React 是用于创建页面的 UI 库。 每个页面组件都应导出一个 React 组件,这些组件在其他地方可以多次使用,然后你就可以发挥 React 的表达力构建丰富的交互内容了。 13 | 14 | <To to="https://reactjs.org/">React 官网</To> 15 | 16 | ## Next.js 17 | 18 | Next.js 是一个轻量级的 React 服务端渲染应用框架。 React 于官方文件内的“推荐的工具链”中提及 Next.js,建议将其作为“使用 Node.js 构建服务器渲染网站”的解决方案。传统的 React 应用程序只能在客户端浏览器中渲染内容,Next.js 扩展了此功能以包括在服务端渲染的应用程序。(部分来自维基百科) 19 | 20 | ## 添加页面 21 | 22 | 为了方便被 Next.js 识别到页面,我们必须将页面的代码存放到 `/pages` 文件夹中,并命名为`[页面名称]/index.jsx`,当然,我们也支持 TypeScript 。 23 | 24 | 现在,我在 `/pages` 文件夹中创建一个新的页面,文件夹为 `hello` ,并命名里面的文件为 `index.jsx`: 25 | 26 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220831133734.png) 27 | 28 | ```jsx 29 | import { NavBar } from '../../components/NavBar'; 30 | 31 | function HelloWorld() { 32 | return ( 33 | <> 34 | <NavBar /> 35 | <div className="w-screen h-screen flex flex-col items-center justify-center text-3xl font-bold"> 36 | <div>Hello World</div> 37 | <div>你好!世界</div> 38 | </div> 39 | </> 40 | ); 41 | } 42 | 43 | export default function Hello() { 44 | return <HelloWorld />; 45 | } 46 | ``` 47 | 48 | 在这个页面中,我简单地定义了一个组件 `HelloWorld`,并将其导出为 `Hello` 页面。在这里面引入了 `NavBar` 组件,因此页面才会产生导航栏。 49 | 50 | ## 添加路由 51 | 52 | 我想要把这个页面添加到导航栏中,因此我需要在 `daymd.config.js` 文件中的 `navItems` 添加一个路由: 53 | 54 | ```js 55 | // 导航栏的选项 56 | navItems: [ 57 | { 58 | name: 'Docs', 59 | to: '/docs', 60 | }, 61 | { 62 | name: 'Blog', 63 | to: '/posts', 64 | }, 65 | { 66 | name: 'Nav', 67 | to: '/website', 68 | }, 69 | // Hello 页面的路由 70 | { 71 | name: 'Hello', 72 | to: '/hello', 73 | }, 74 | ], 75 | ``` 76 | 77 | 然后导航栏就出现了 `Hello` 页面了。 78 | 79 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220831135317.png) 80 | 81 | 点击进入: 82 | 83 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220831135347.png) 84 | 85 | 怎么样?添加一个页面是不是很简单? 86 | 87 | <Tips title="遇到问题?">如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 issue 提交界面.</Tips><To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 88 | -------------------------------------------------------------------------------- /content/docs/005-improve/001-csschange.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 样式修改 3 | excerpt: 样式修改 4 | date: 2022-08-31 5 | --- 6 | 7 | `styles/global.css` 文件为你提供了样式修改的入口,你可以在这里修改全局样式。 8 | 9 | `styles/markdown.css` 文件为你提供了 Markdown 样式修改的入口,你可以在这里修改 Markdown 样式。 10 | 11 | <Tips title="遇到问题?"> 12 | 如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 13 | issue 提交界面. 14 | <To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 15 | </Tips> 16 | -------------------------------------------------------------------------------- /content/docs/005-improve/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 进阶指南 3 | excerpt: 进阶指南 4 | date: 2022-08-31 5 | --- 6 | 7 | 经过一些坎坷,我们很快就让我们的网站部署上线了,当然,前面都是一些基础的步骤, Daymd 作为一个 Next.js 应用,它有着很强的可拓展性,你可以在 Daymd 的基础上自己创建页面以及其他功能。 8 | 现在,我们来看看 Daymd 的进阶指南。 9 | 10 | ## 需要的基础 11 | 12 | 这一部分需要涉及到前端开发技术。你可能需要掌握基本的 html 、 css 、JavaScript 等技术,在创建页面时,Daymd 要求你创建的是 React 页面,因此要求你掌握 React 基础。 13 | 14 | ## 页面创建 15 | 16 | 这一章节会帮助你创建一个自定义的页面,并且能够通过路由访问,在 `daymd.config.js` 中的 `navItems` 配置可以路由。 17 | 18 | ## 基础样式 19 | 20 | 这一章节会带你了解可以通过全局 css 定义的样式如何进行修改,从而进一步对页面进行自定义。 21 | 22 | <Tips title="遇到问题?">如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 issue 提交界面.</Tips><To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 23 | -------------------------------------------------------------------------------- /content/docs/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Daymd:介绍 3 | excerpt: 快速上手 4 | date: 2022-08-25 5 | --- 6 | 7 | ## 介绍 8 | 9 | ### 特点 10 | 11 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/daymdBanner.png) 12 | 13 | **Daymd** 是一个基于 `Next.js` 、 `Contenelayer` 、 `Tailwind CSS` 、 `DaisyUI` 的静态网站生成器。它高度抽象,把几乎所有能够自定义的地方都抽象成了一个个 API 接口,同时它又高度自由,它本身就是一个单纯的 Next.js 应用,你可以通过 `React.js` 语法创建属于自己的页面和组件,并在 NPM 市场寻找自己想要的插件进行安装。**Daymd**让你: 14 | 15 | - **零基础上手**。只需要填写 `API` 接口的参数,就可以搭建出优质美观的网站。 16 | - **专注于内容**。进行简单的设置后,您就可以专注于 Markdown 文件的编写,打造以文档为中心的网站。 17 | - **高度自定义**。为你提供 28 种美观的主题,同样也是填写参数即可使用,让你的网站与众不同。此外, Daymd 不封装源代码,而是将所有源代码都提供给您,您可以在这基础上修改源代码达到你想要的效果。 18 | 19 | 实际上,这是一个**轮子**,市面上已经有 VuePress 、 Hexo 、 Docusaurus 等优秀的博客生成器,并且它们对 Markdown 的支持更好,功能更完善,体验更优秀。但!请把 Daymd 当成一个玩具,从中去体验造轮子的”快乐“。并且,我们主打的是面向 **零基础** !上面提到的工具的文档大多面向程序员而写,没有相关的基础很难看懂并使用它,而我们将从盘古开天地讲起,让你从浅入深部署 Daymd 并通过一个**免费的**域名来访问他。我希望 Daymd 可以成为你 CS 学习生涯的起点,它非常友好,可以**笑着和你说你好**,告诉你操作的每个细节,同时**它也愿意笑着和你说再见**,当你去拥抱更好的工具的时候。但是别忘了给我留下一个**小小的 Star**,举手之劳! 20 | 21 | ### 前提准备 22 | 23 | 一台 💻 | 是的,你只需要有一台能够访问互联网的电脑。 24 | 25 | - Q:需要有 Node.js 等开发环境吗? 26 | 27 | > 不需要。 28 | 29 | - Q:需要有 HTML 、 CSS 、 JavaScript 知识的基础吗? 30 | 31 | > 不需要。 32 | 33 | - Q:需要有其他编程知识的基础吗? 34 | 35 | > 不需要。 36 | 37 | - Q:需要学习过上面罗列的框架和工具如 `Next.js` 吗? 38 | 39 | > 不需要。 40 | 41 | - Q:需要访问外网吗? 42 | 43 | > 可能需要。 44 | -------------------------------------------------------------------------------- /content/docs/index.zh.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Daymd:介绍 3 | excerpt: 快速上手 4 | date: 2022-08-25 5 | --- 6 | 7 | ## 介绍 8 | 9 | ### 特点 10 | 11 | ![1](https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/daymdBanner.png) 12 | 13 | **Daymd** 是一个基于 `Next.js` 、 `Contenelayer` 、 `Tailwind CSS` 、 `DaisyUI` 的静态网站生成器。它高度抽象,把几乎所有能够自定义的地方都抽象成了一个个 API 接口,同时它又高度自由,它本身就是一个单纯的 Next.js 应用,你可以通过 `React.js` 语法创建属于自己的页面和组件,并在 NPM 市场寻找自己想要的插件进行安装。**Daymd**让你: 14 | 15 | - **零基础上手**。只需要填写 `API` 接口的参数,就可以搭建出优质美观的网站。 16 | - **专注于内容**。进行简单的设置后,您就可以专注于 Markdown 文件的编写,打造以文档为中心的网站。 17 | - **高度自定义**。为你提供 28 种美观的主题,同样也是填写参数即可使用,让你的网站与众不同。此外, Daymd 不封装源代码,而是将所有源代码都提供给您,您可以在这基础上修改源代码达到你想要的效果。 18 | 19 | 实际上,这是一个**轮子**,市面上已经有 VuePress 、 Hexo 、 Docusaurus 等优秀的博客生成器,并且它们对 Markdown 的支持更好,功能更完善,体验更优秀。但!请把 Daymd 当成一个玩具,从中去体验造轮子的”快乐“。并且,我们主打的是面向 **零基础** !上面提到的工具的文档大多面向程序员而写,没有相关的基础很难看懂并使用它,而我们将从盘古开天地讲起,让你从浅入深部署 Daymd 并通过一个**免费的**域名来访问他。我希望 Daymd 可以成为你 CS 学习生涯的起点,它非常友好,可以**笑着和你说你好**,告诉你操作的每个细节,同时**它也愿意笑着和你说再见**,当你去拥抱更好的工具的时候。但是别忘了给我留下一个**小小的 Star**,举手之劳! 20 | 21 | ### 前提准备 22 | 23 | 一台 💻 | 是的,你只需要有一台能够访问互联网的电脑。 24 | 25 | - Q:需要有 Node.js 等运行环境吗? 26 | 27 | > 不需要。 28 | 29 | - Q:需要有 HTML 、 CSS 、 JavaScript 知识的基础吗? 30 | 31 | > 不需要。 32 | 33 | - Q:需要有其他编程知识的基础吗? 34 | 35 | > 不需要。 36 | 37 | - Q:需要学习过上面罗列的框架和工具如 `Next.js` 吗? 38 | 39 | > 不需要。 40 | 41 | - Q:需要访问某些特殊网络吗? 42 | 43 | > 可能需要。 44 | -------------------------------------------------------------------------------- /content/posts/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inannan423/Daymd/df32a865a2e951fac5f4fd124122302367871c3c/content/posts/.gitkeep -------------------------------------------------------------------------------- /content/posts/2022-08-31-blogone/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 测试博客 3 | excerpt: 测试博客 4 | date: 2022-08-30 5 | backpic: url(https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220831154801.png) 6 | --- 7 | 8 | ## 测试博客 9 | 10 | 这是一篇测试博客 11 | -------------------------------------------------------------------------------- /content/posts/2022-08-31-blogtwo/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 测试博客 3 | excerpt: 测试博客 4 | date: 2022-08-30 5 | backpic: url(https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220831154801.png) 6 | --- 7 | 8 | ## 测试博客 9 | 10 | 这是一篇测试博客 11 | -------------------------------------------------------------------------------- /content/posts/2022-09-01-blogthree/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 测试博客 3 | excerpt: 测试博客 4 | date: 2022-09-01 5 | backpic: url(https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220831154801.png) 6 | --- 7 | 8 | ## 测试博客 9 | 10 | 这是一篇测试博客 11 | -------------------------------------------------------------------------------- /content/posts/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 感谢到访 3 | excerpt: 感谢到访 4 | date: 2022-08-25 5 | backpic: url(https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/mainpageBk.png) 6 | --- 7 | 8 | ## 缘起 9 | 10 | 做这个项目本身是出于对 `Tailwindcss` 以及 `DaisyUI` 的好奇。笔者觉得发现了一个宝藏 11 | css 工具,就想要用它们组合出一个东西出来,恰巧最近折腾了很久的博客,因此打算搭建一个简单的博客生成器。但是博客生成器纷繁众多,总得有点特点吧!所以我就把文档写的很详细,想把它作为一个面向初学者的开源产品。并且结合在线 IDE 工具以及在线部署工具,让 Daymd 博客的搭建能够从创建到发布均在浏览器完成。**不需要搭建任何本地环境,不需要下载任何软件**,就能够完成一个个人网站的搭建,我觉得这是很酷的。 12 | 13 | 相比其他工具,它们的文档往往面向程序员而写,初学者往往很难看懂文档(甚至它们没有中文版)。更别说完成一篇博客搭建了,目前基于 React 或者 Vue 的站点生成器都需要 Nodejs 本地环境,对于很多初学者来说,这是一个坎(比如几个月前的我)。而使用 Daymd ,你可能只需要一部没有安装任何环境的电脑甚至一台平板、一部手机,都能完成这件事。 14 | 15 | ## 感悟 16 | 17 | 这只是一个玩具,最后也会尘封在我的 GitHub 仓库中,我可以预料到很少会有人来到这个站点,更少会有人阅读至此,但是这个工具是我半个月之内的汗水,他对我的意义已经达到了。如果你是初学者,我希望你用一用,留给我一个 Star ,谢谢你,如果你是一名程序员,我希望你不要点进仓库看我的代码,它们写的很混乱,一团糟。但如果你愿意为我的项目提交一个 pull request ,我十分感谢。 18 | 19 | ## 致谢 20 | 21 | 在本项目构建过程中,参考了很多开源项目,由于对 `contentlayer` 很陌生,不会使用,因此借鉴了 [chioio](https://github.com/chioio) 个人博客的源码,在导航栏部分,借鉴并使用了 [愧怍](https://github.com/kuizuo) 的源码。如有侵权,请联系我删除。 22 | 23 | ## 溜了 24 | 25 | 笔者刚上大三,已经开始上课了!现在要溜去干别的事儿了!再次感谢你看到这里,志同者同行,其他人随便。 26 | 27 | ## 寻求帮助? 28 | 29 | <Tips title="遇到问题?"> 30 | 如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 31 | issue 提交界面. 32 | </Tips> 33 | <To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 34 | -------------------------------------------------------------------------------- /content/posts/index.zh.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 感谢到访 3 | excerpt: 感谢到访 4 | date: 2022-08-25 5 | backpic: url(https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/mainpageBk.png) 6 | --- 7 | ## 缘起 8 | 9 | 做这个项目本身是出于对 `Tailwindcss` 以及 `DaisyUI` 的好奇。笔者觉得发现了一个宝藏 10 | css 工具,就想要用它们组合出一个东西出来,恰巧最近折腾了很久的博客,因此打算搭建一个简单的博客生成器。但是博客生成器纷繁众多,总得有点特点吧!所以我就把文档写的很详细,想把它作为一个面向初学者的开源产品。并且结合在线 IDE 工具以及在线部署工具,让 Daymd 博客的搭建能够从创建到发布均在浏览器完成。**不需要搭建任何本地环境,不需要下载任何软件**,就能够完成一个个人网站的搭建,我觉得这是很酷的。 11 | 12 | 相比其他工具,它们的文档往往面向程序员而写,初学者往往很难看懂文档(甚至它们没有中文版)。更别说完成一篇博客搭建了,目前基于 React 或者 Vue 的站点生成器都需要 Nodejs 本地环境,对于很多初学者来说,这是一个坎(比如几个月前的我)。而使用 Daymd ,你可能只需要一部没有安装任何环境的电脑甚至一台平板、一部手机,都能完成这件事。 13 | 14 | ## 感悟 15 | 16 | 这只是一个玩具,最后也会尘封在我的 GitHub 仓库中,我可以预料到很少会有人来到这个站点,更少会有人阅读至此,但是这个工具是我半个月之内的汗水,他对我的意义已经达到了。如果你是初学者,我希望你用一用,留给我一个 Star ,谢谢你,如果你是一名程序员,我希望你不要点进仓库看我的代码,它们写的很混乱,一团糟。但如果你愿意为我的项目提交一个 pull request ,我十分感谢。 17 | 18 | ## 致谢 19 | 20 | 在本项目构建过程中,参考了很多开源项目,由于对 `contentlayer` 很陌生,不会使用,因此借鉴了 [chioio](https://github.com/chioio) 个人博客的源码,在导航栏部分,借鉴并使用了 [愧怍](https://github.com/kuizuo) 的源码。如有侵权,请联系我删除。 21 | 22 | ## 溜了 23 | 24 | 笔者刚上大三,已经开始上课了!现在要溜去干别的事儿了!再次感谢你看到这里,志同者同行,其他人随便。 25 | 26 | ## 寻求帮助? 27 | 28 | <Tips title="遇到问题?">如需要帮助,可以选择给电子邮箱发邮件: `czhorange@foxmail.com` 或者点击进入 issue 提交界面.</Tips><To to="https://github.com/inannan423/Daymd/issues">寻求帮助</To> 29 | -------------------------------------------------------------------------------- /contentlayer.config.ts: -------------------------------------------------------------------------------- 1 | import { defineDocumentType, makeSource } from "contentlayer/source-files"; 2 | import configs from "./daymd.config"; 3 | import PrettyCode from "rehype-pretty-code"; 4 | 5 | import { CONTENT_DIR } from "./src/configs/constants"; 6 | import DocType from "./src/contentlayer/types/doc"; 7 | import PostType from "./src/contentlayer/types/post"; 8 | 9 | // 代码高亮. 10 | const options = { 11 | theme: configs.mdCodeTheme, 12 | onVisitLine(node) { 13 | if (!node.children.length) { 14 | node.children = [{ type: "text", value: " " }]; 15 | } 16 | }, 17 | onVisitHighlightedLine(node) { 18 | node.properties.className.push("highlighted"); 19 | }, 20 | onVisitHighlightedWord(node) { 21 | node.properties.className = ["word"]; 22 | }, 23 | }; 24 | 25 | export default makeSource({ 26 | contentDirPath: CONTENT_DIR, 27 | documentTypes: [DocType, PostType], 28 | mdx: { rehypePlugins: [[PrettyCode, options]] }, 29 | }); 30 | -------------------------------------------------------------------------------- /daymd.config.js: -------------------------------------------------------------------------------- 1 | // 全局API接口,设置 2 | const configs = { 3 | // 网站名称 4 | title: "Daymd.", 5 | // hero模式,0:不显示;1:背景图模式;2:宇宙模式;3:博客模式; 6 | heroMode: 3, 7 | // 宇宙模式设置,限heroMode:2 8 | heroModeConfig: { 9 | // 星星数量,number,要求:<1000 10 | starsCount: 250, 11 | // 星星颜色,string 12 | starsColor: "#ffffff", 13 | // 星星旋转速度,number 14 | starsRotationSpeed: 3, 15 | // 彗星出现的频度,number,若值设置为0,隐藏彗星 16 | cometFrequence: 2, 17 | // 星云强度,number,即两侧颜色深度 18 | nebulasIntensity: 0, 19 | // 太阳系数量,number,若设置为0,隐藏 20 | sunScale: 1, 21 | // 行星数量,number,若设置为0,隐藏 22 | planetsScale: 1, 23 | // 太阳系轨道,number,要求<100 24 | solarSystemOrbite: 65, 25 | // 轨道速度,number 26 | solarSystemSpeedOrbit: 100, 27 | }, 28 | // 大文字,限heroMode:1|2 29 | heroText: "Do it all with API.", 30 | // 大文字下的说明文字,限heroMode:1 31 | heroContent: 32 | "A blog site builder built with Next.js, Tailwind, DaisyUI, Contentlayer. Almost everything can be configured via the API interface. Get started quickly with zero basics.", 33 | // 标签图标 34 | favicon: 35 | "https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/daymd_logo1.svg", 36 | // NavBar 的样式,参数值 1、2 37 | navTheme: 2, 38 | // 导航栏logo是否显示,0为不显示,1为显示 39 | isNavLogo: 1, 40 | // 博客创建时间,string,格式:YYYY-MM-DD 41 | buildTime: "2020-08-31", 42 | // 导航栏logo图片链接 43 | navLogo: 44 | "https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/daymd_logo1.svg", 45 | // 导航栏透明度,bg-opacity-请不要修改,后面的数字越大越不透明,值为每10增加,范围0~100 46 | // 例如56、45等非整十的值无效 47 | // bg-opacity-xx后面可以添加其他 Tailwind 样式类 48 | navOpacity: "bg-opacity-10", 49 | // Hero的背景图片,限heroMode:1,使用 https://api.maho.cc/random-img/pc.php 接口可以每刷新一次得到不同的二次元背景,详见文档 50 | heroBg: "url(https://api.maho.cc/random-img/pc.php)", 51 | // Hero 按钮上的文字,限heroMode:1 52 | heroButton: "Get Start", 53 | // Hero 按钮跳转的 Link 链接,限heroMode:1 54 | heroButtonLink: "/posts/change-me", 55 | // 主页设置,限heroMode:3 56 | theme2Setting: { 57 | // 右边栏作者头像 58 | avatar: 59 | "https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/20220710133634.png", 60 | // 背景图大小,1为顶部小图,2为整页图,3为混合模式 61 | backSize: 2, 62 | // 背景图链接,url不可省略 63 | topImg: "url(https://api.maho.cc/random-img/pc.php)", 64 | // 右边作者栏作者名称 65 | authorName: "Jetzihan", 66 | // 下面的按钮是否使用中文 67 | zhan: 1, 68 | // 技术栈 69 | techLinks: [ 70 | { 71 | tech: "Vue", 72 | styles: "bg-green-200 text-green-900", 73 | }, 74 | { 75 | tech: "React", 76 | styles: "bg-blue-200 text-blue-900", 77 | }, 78 | { 79 | tech: "Python", 80 | styles: "bg-yellow-200 text-yellow-900", 81 | }, 82 | ], 83 | // 个人格言 84 | Words: "风筝有风,海豚有海。", 85 | socialIcons: [ 86 | { 87 | name: "GitHub", 88 | svgPath: 89 | "https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/icon-github-1.svg", 90 | link: "https://github.com/inannan423", 91 | }, 92 | { 93 | name: "掘金", 94 | svgPath: 95 | "https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/icon-juejin-1.svg", 96 | link: "https://juejin.cn", 97 | }, 98 | { 99 | name: "CSDN", 100 | svgPath: 101 | "https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/icon-csdn-1.svg", 102 | link: "www.csdn.com", 103 | }, 104 | { 105 | name: "bilibili", 106 | svgPath: 107 | "https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/icon-bilibili-1.svg", 108 | link: "https://bilibili.com", 109 | }, 110 | { 111 | name: "gitee", 112 | svgPath: 113 | "https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/icon-gitee-1.svg", 114 | link: "www.gitee.com", 115 | }, 116 | { 117 | name: "weibo", 118 | svgPath: 119 | "https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/icon-wb-1.svg", 120 | link: "www.weibo.com", 121 | }, 122 | { 123 | name: "Zhihu", 124 | svgPath: 125 | "https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/icon-zh-1.svg", 126 | link: "www.weibo.com", 127 | }, 128 | { 129 | name: "抖音", 130 | svgPath: 131 | "https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/icon-dy-1.svg", 132 | link: "www.weibo.com", 133 | }, 134 | ], 135 | }, 136 | isHeroButton: 1, 137 | // 导航栏的选项 138 | navItems: [ 139 | { 140 | name: "Docs", 141 | to: "/docs", 142 | }, 143 | { 144 | name: "Blog", 145 | to: "/posts", 146 | }, 147 | { 148 | name: "Nav", 149 | to: "/website", 150 | }, 151 | // ...可以继续添加 152 | ], 153 | // 导航栏上面的图标,建议使用 svg 格式,外链 154 | // Todo 155 | navIcons: [ 156 | { 157 | name: "Github", 158 | icon: "https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/icon-github-1.svg", 159 | to: "https://github.com/inannan423", 160 | }, 161 | //... 可以继续添加 162 | ], 163 | // 选用的主题 164 | themeSelect: [ 165 | { 166 | theme: "winter", 167 | }, 168 | { 169 | theme: "forest", 170 | }, 171 | { 172 | theme: "dark", 173 | }, 174 | 175 | { 176 | theme: "night", 177 | }, 178 | { 179 | theme: "cupcake", 180 | }, 181 | { 182 | theme: "lofi", 183 | }, 184 | // ...可以继续添加,请参考文档中的所有主题列表 185 | ], 186 | // 是否需要大页脚,1:需要,0:不需要 187 | ifFootItems: 1, 188 | // 大页脚不存在时,底部小页脚中是否需要切换Theme按钮,建议全页只保留一个主题切换按钮 189 | ifFootTheme: 0, 190 | // 页脚链接,ifFootItems: 1 才生效 191 | FooterItems: [ 192 | // 每一列 193 | { 194 | label: "本站", 195 | // 列中的每一行 196 | items: [ 197 | { 198 | key: 0, 199 | // 链接名称 200 | name: "部署指南", 201 | // 链接地址 202 | to: "/docs", 203 | blank: 0, 204 | }, 205 | { 206 | key: 1, 207 | name: "博客", 208 | to: "/posts", 209 | blank: 0, 210 | }, 211 | { 212 | key: 1, 213 | name: "快速链接", 214 | to: "/website", 215 | blank: 0, 216 | }, 217 | // ... 可继续添加 218 | ], 219 | }, 220 | { 221 | label: "技术支持", 222 | items: [ 223 | { 224 | key: 0, 225 | name: "React", 226 | to: "https://react.docschina.org/", 227 | blank: 1, 228 | }, 229 | { 230 | key: 1, 231 | name: "Next.js", 232 | to: "https://nextjs.org/", 233 | blank: 1, 234 | }, 235 | { 236 | key: 2, 237 | name: "Contentlayer", 238 | to: "https://www.contentlayer.dev/", 239 | blank: 1, 240 | }, 241 | { 242 | key: 3, 243 | name: "DaisyUI", 244 | to: "https://daisyui.com/", 245 | blank: 1, 246 | }, 247 | { 248 | key: 4, 249 | name: "Tailwind", 250 | to: "https://tailwindcss.com/", 251 | blank: 1, 252 | }, 253 | ], 254 | }, 255 | { 256 | label: "链接", 257 | items: [ 258 | { 259 | key: 0, 260 | name: "Jetzihan", 261 | to: "https://jetzihan.netlify.app", 262 | blank: 1, 263 | }, 264 | ], 265 | }, 266 | // ... 可继续添加 267 | ], 268 | // 是否支持主题切换,0为不支持,1为支持 269 | showTheme: 1, 270 | // 页脚 Logo 271 | footLogo: 272 | "https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/daymd_logo1.svg", 273 | // Logo下的加粗文字 274 | footText: "Daymd by Jetzihan.", 275 | // 加粗文字下的文字 276 | footTextNormal: "Made with ❤ by Chengzihan.", 277 | socialIcon: [ 278 | { 279 | name: "bilibili", 280 | icon: "https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/bzhan.svg", 281 | to: "https://bilibili.com", 282 | }, 283 | { 284 | name: "CSDN", 285 | icon: "https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/csdn.svg", 286 | to: "https://csdn.com", 287 | }, 288 | { 289 | name: "稀土掘金", 290 | icon: "https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/xitujuejin.svg", 291 | to: "https://juejin.cn/", 292 | }, 293 | ], 294 | // 是否启用回到顶部按钮:1是,0否 295 | ifBackTop: 1, 296 | // 回到顶部按钮内的文字,您可以换成”Top“或者”🌵“甚至”❤“等字符 297 | backTopText: "↑", 298 | // 笔记页面设置 ************************************ 299 | // 笔记页面标题,建议为tutorial、notes等 300 | notePageTitle: "介绍", 301 | // 笔记、博客右侧边粗体标题文字 302 | rightContentText: "Topics", 303 | // 是否显示面包屑,1:显示。0:不显示。 304 | ifBread: 1, 305 | // 是否显示右边主题栏,1:显示。0:不显示。 306 | ifRightBar: 1, 307 | // 在博客页面是否显示右边主题栏,1:显示。0:不显示。 308 | ifPostRightBar: 1, 309 | // 特殊卡片的标题文字,支持中英文和emoji 310 | cardsInDoc: { 311 | // "注意"卡片的固定文字显示,示例:”注意“、”Warning!“、”⚠“、”警告“ 312 | Warning: "注意", 313 | Tip: "提示", 314 | Danger: "危险", 315 | Note: "笔记", 316 | Example: "举例", 317 | }, 318 | // doc和post的背景图片,默认为空,即不显示 319 | // docPostBgImg: "url(https://api.maho.cc/random-img/pc.php)", 320 | docPostBgImg: "url(https://api.maho.cc/random-img/pc.php)", 321 | // 博客页面的标题 322 | postPageTitle: "我的博客", 323 | // Markdown中代码块主题样式 324 | /** 325 | * 可用主题: 326 | * 'monokai' 327 | * 'monokai' 328 | * 'nord' 329 | * 'one-dark-pro' 330 | * 'poimandres' 331 | * 'rose-pine-dawn' 332 | * 'rose-pine-moon' 333 | * 'rose-pine' 334 | * 'slack-dark' 335 | * 'slack-ochin' 336 | * 'solarized-dark' 337 | * 详见daymd文档 338 | */ 339 | mdCodeTheme: "one-dark-pro", 340 | // Doc页面时间显示前面的文字 341 | timeText: "Last Updated:", 342 | // post页面时间显示前面的文字 343 | postTimeText: "Date:", 344 | // 文章底部是否显示附属链接,0为不显示 345 | ifDocLink: 1, 346 | // 文章底部的附属链接文字 347 | docLinkText: "文档地址", 348 | // 文章底部附属链接地址,你可以填写你的Github仓库,也可以为你的公众号引流 349 | docLinkUrl: "https://github.com/inannan423/Daymd/tree/main/content/docs", 350 | // 个人导航集合标题 351 | navTitle: "导航分类", 352 | // 是否显示 Banner 图片,1显示,0不显示 353 | ifNavBanner: 1, 354 | // 导航 Banner 图片链接 355 | navBanner: 356 | "url(https://jetzihan-img.oss-cn-beijing.aliyuncs.com/blog/NavBanner.png)", 357 | }; 358 | 359 | module.exports = configs; 360 | -------------------------------------------------------------------------------- /navData/friend.ts: -------------------------------------------------------------------------------- 1 | export type Friend = { 2 | title: string; 3 | description?: string; 4 | website: string; 5 | avatar?: any; 6 | }; 7 | 8 | export const Friends: Friend[] = [ 9 | { 10 | title: "Jetzihan", 11 | description: "Daymd 作者的个人网站", 12 | website: "https://jetzihan.netlify.app/", 13 | avatar: "https://avatars.githubusercontent.com/u/83146544?v=4", 14 | }, 15 | ]; 16 | 17 | export function sortFriend() { 18 | let result = Friends; 19 | return result; 20 | } 21 | -------------------------------------------------------------------------------- /next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// <reference types="next" /> 2 | /// <reference types="next/image-types/global" /> 3 | -------------------------------------------------------------------------------- /next-i18next.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | i18n: { 3 | defaultLocale: "en", 4 | locales: ["en", "zh"], 5 | }, 6 | // localePath: path.resolve('./public/static/locales'), 7 | }; 8 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | // @ts-check. 2 | const { withContentlayer } = require("next-contentlayer"); 3 | const { i18n } = require("./next-i18next.config"); 4 | 5 | /** @type {import('next').NextConfig} */ 6 | const nextConfig = { 7 | reactStrictMode: true, 8 | i18n, 9 | }; 10 | 11 | module.exports = withContentlayer(nextConfig); 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Daymd", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start" 9 | }, 10 | "dependencies": { 11 | "@flodlc/nebula": "^1.0.56", 12 | "classnames": "^2.3.1", 13 | "clsx": "^1.2.1", 14 | "contentlayer": "latest", 15 | "daisyui": "^2.24.0", 16 | "date-fns": "^2.29.1", 17 | "framer-motion": "^7.2.1", 18 | "material-ui": "^0.20.2", 19 | "moment": "^2.29.4", 20 | "next": "12.2.5", 21 | "next-contentlayer": "latest", 22 | "next-i18next": "^12.0.0", 23 | "react": "18.2.0", 24 | "react-back2top": "^0.1.6", 25 | "react-dom": "18.2.0", 26 | "react-icons": "^4.4.0", 27 | "react-rellax": "^1.0.3", 28 | "react-scroll-to-top": "^3.0.0", 29 | "react-scroll-up": "^1.3.7", 30 | "react-tooltip": "^4.2.21", 31 | "react-use": "^17.4.0", 32 | "rehype-pretty-code": "^0.3.2", 33 | "rellax": "^1.12.1", 34 | "shiki": "^0.11.1", 35 | "theme-change": "^2.2.0", 36 | "use-immer": "^0.7.0", 37 | "vanilla-back-to-top": "^7.2.1" 38 | }, 39 | "devDependencies": { 40 | "@types/react": "18.0.17", 41 | "autoprefixer": "^10.4.4", 42 | "postcss": "^8.4.12", 43 | "tailwindcss": "^3.0.24", 44 | "typescript": "4.7.4" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import Head from "next/head"; 2 | // import NavBar from '../components/NavBar.jsx' 3 | import "../styles/globals.css"; 4 | import React from "react"; 5 | import { Header } from "../components/Header"; 6 | import { NavBar } from "../components/NavBar"; 7 | import { Footer } from "../components/Footer"; 8 | import { Hero } from "../components/Hero"; 9 | import { CoolHead } from "../components/CoolHead"; 10 | import ScrollToTop from "react-scroll-to-top"; 11 | import configs from "../daymd.config"; 12 | 13 | export default function MyApp({ Component, pageProps }) { 14 | return ( 15 | <> 16 | <Head> 17 | <title>{configs.title} 18 | 19 | 20 | {/* */} 21 | 22 |
28 | 33 | {configs.backTopText} 34 |

35 | } 36 | /> 37 |
38 |
39 | 40 |
41 | 42 |