关于博客搭建:使用-github-和-Deno-Deploy-搭建一个博客网站

这个可能是目前最简略的搭建博客网站的形式了。你只须要有一个github账号就行了。 github 是一个用来放代码的网站,程序员大多应用此网站寄存本人的代码,和他人交换本人/他人的代码的bug…… Deno Deploy 是一个服务部署网站,你把代码交给它,它就会把你的代码跑起来了。相似于腾讯云、阿里云之类的,比他们更简略更易用,不必再本人买机器装零碎blabla等繁琐的操作了。只不过是只能部署用Deno 写的服务。能够应用 github 的账号登录。 简略概括一下步骤: 在 github 上创立一个代码仓库,用来寄存博客零碎的代码和内容。在 Deno Deploy 平台上创立一个我的项目,关联上一步的代码仓库。在github上编写博客内容,推送到github仓库后,等个10s左右,Deno Deploy 会主动部署实现。创立 github 仓库,寄存博客代码和内容0. 创立代码仓库,能够抉择公有的或公开我的项目依照你的须要填你本人起的名字。抉择Public的话,他人就能看到你的代码仓库外面的内容,留神不要放些敏感内容。 1. 配置博客相干信息在我的项目根目录下创立一个名为main.tsx的文件,文件内容如下(依据须要改成你的相干信息): import blog from "https://deno.land/x/blog/blog.tsx";blog({ author: "Dino", title: "My Blog", description: "The blog description.", avatar: "https://deno-avatar.deno.dev/avatar/83a531.svg", avatarClass: "rounded-full", links: [ { title: "Email", url: "mailto:bot@deno.com" }, { title: "GitHub", url: "https://github.com/denobot" }, { title: "Twitter", url: "https://twitter.com/denobot" }, ], lang: "zh",});更多具体设置,看 deno_blog 文档 2. 创立博客内容一个小技巧:在github 的仓库主页,按句号.对应的按键,能够用github的在线编辑器关上此仓库,能够间接在线编辑提交到代码仓库。创立文件夹posts,留神,这个文件夹名字固定是这个;而后在文件夹中创立第一篇博客,比方这里创立了一个名为hello_world.md,的文件作为第一篇博客(留神:文件名称不要有空格和中文),内容如下: ---title: 第一篇博客publish_date: 2022-11-20tags: ['hello-world']---这是我的第一篇博客!这里是博客内容将内容推送到 github 的代码仓库中。 ...

November 21, 2022 · 1 min · jiezi

关于博客搭建:Hexo搭建基操配置

初始化Hexo首先须要以下装置环境,间接在官网下载即可 Node.jsGit环境筹备好后,装置Hexo npm install -g hexo-cli装置后在指定文件夹创立我的项目 hexo init <folder>cd <folder>npm install抉择主题 Hexo初始化胜利后,而后须要抉择一个丑陋的主题,这个举荐间接在官网上找,主题 选中主题后下载到我的项目themes文件夹而后批改根目录下的_config.yml文件theme: '主题名,也就是themes文件夹里的名字'hexo最罕用的有以下几个命令 启动服务:hexo server 或 hexo s新建文章:hexo new "文章名字"新建动态页面:hexo new page "页面名字"生成public文件夹:hexo generate 或 hexo g革除public文件夹:hexo clean部署:hexo deploy 或 hexo d部署到GithubGithub有收费提供搭建动态网站的性能,所以hexo举荐间接放到GitHub Page,依照以下步骤进行部署。 首先新建一个源码repo,倡议抉择Private,这个用来放hexo我的项目代码,不对外开放本地仓库运行以下命令提交代码 git init:git初始化git add .: 将所有代码增加到暂存区git commit -m "first commit":提交本次commitgit remote add origin '近程仓库地址':增加近程仓库地址git push -u origin main:推送代码而后再新建一个仓库,名字为 github名字.github.io,这个仓库用于放部署后的代码装置Hexo部署插件 npm install hexo-deployer-git批改根目录下的 _config.yml deploy: type: git repo: 部署仓库地址 branch: main最初执行hexo deploy命令就能够在github名字.github.io看到博客了SSH + github Actions主动部署Github Actions是github专用的继续集成脚本,用于主动执行工作流程,SSH能够通过建设密钥免密登录,这两个联合就能达到主动部署的成果首先通过ssh-keygen生成密钥,ssh-keygen -t rsa -C "Github 的邮箱地址"而后github配置ssh,配置门路:github -> Settings –> SSH and GPG keys git仓库增加密钥公有变量,配置门路:repo -> Settings -> Secrets,点击New repository secret,name能够自定义,次要是接下来的deploy.yaml文件须要应用,Secret填写你生成的密钥而后根目录下新建.github/workflows/deploy.yaml,并填写以下内容 ...

September 7, 2022 · 1 min · jiezi

关于博客搭建:Hugo-even-GitHub-Pages-Utterances搭建个人博客

前言多年前基于Jekyll和GitHub Pages搭建的博客款式总是出问题,调研了下目前最风行的动态博客次要有3个: hexo:基于Node.js,开源地址:https://github.com/hexojs/hexoHugo:基于Go实现,开源地址:https://github.com/gohugoio/hugogridea:国产,集体保护,开源地址:https://github.com/getgridea/grideaHugo目前GitHub上star最多,我关注的几个技术博主根本都选用的Hugo,再加上Hugo基于Go实现,有bug我也能够思考本人解决,于是果决抉择了Hugo。 最终成果参考https://jincheng9.github.io/ 步骤Hugo装置Hugo(以Mac为例) $ brew install hugo创立本地文件夹,用于存储博客内容,假如文件夹叫blog $ hugo new site blogblog目录下的文件内容如下: drwxr-xr-x 9 zhangjincheng staff 288 12 21 14:46 .drwxr-xr-x 17 zhangjincheng staff 544 12 21 14:46 ..drwxr-xr-x 3 zhangjincheng staff 96 12 21 14:46 archetypes-rw-r--r-- 1 zhangjincheng staff 82 12 21 14:46 config.tomldrwxr-xr-x 2 zhangjincheng staff 64 12 21 14:46 contentdrwxr-xr-x 2 zhangjincheng staff 64 12 21 14:46 datadrwxr-xr-x 2 zhangjincheng staff 64 12 21 14:46 layoutsdrwxr-xr-x 2 zhangjincheng staff 64 12 21 14:46 staticdrwxr-xr-x 2 zhangjincheng staff 64 12 21 14:46 themeseven主题给Hugo配置even主题: ...

December 21, 2021 · 1 min · jiezi

关于博客搭建:使用Cloudflare和notion搭建自己的博客

欢送拜访我的集体博客ximikang.icu应用Cloudflare和notion搭建本人的博客应用过Nation的小伙伴肯定在某个时刻冒出过这样子的想法:这个笔记利用这么好用,而且是基于Web端开发的,那为什么不能够用他来作为我本人的博客呢?这样我是不是能够用记笔记的形式来疾速的实现和保护本人的博客了呢? 我搭建的集体博客,欢送大家拜访。https://notion.ximikang.icu/ 购买一个域名并将域名转移到Cloudflare首先咱们须要将域名的域名服务器设置为 Cloudflare 的域名服务器,这样就能够应用 Cloudflare 的 DNS 服务了。 注册Cloudflare ,而后在这里增加本人的域名: 将你的域名指向notion切换到 dns 页面,增加一条 CNAME 记录,如果你本人的二级域名为 blog.xxx.com,那么名称那就填 blog,指标填 Notion 的域名,保留。 或者须要将主域名设置为则为 留神须要将代理状态切换至已代理,这样能力用cloudflare的收费CDN。 增加后下方就会显示已增加的域名,点击已增加的域名进入设置页面。 配置Cloudflare的Web Worker配置workder使得咱们拜访咱们下面定义的http申请能够主动改写。 首先治理Workers,新建一个对应的notion的worker。 获取notion页面中的链接ID,如图中的id须要在worker配置中应用。 创立worker后编辑worker,将如下代码复制到worker中。 /* CONFIGURATION STARTS HERE */ /* 增加域名 notion.ximikang.icu*/ const MY_DOMAIN = ''; /* 增加方才的id 例如: '': 'bb1678c7e8fe47b29bf49aac08aebbb', */ const SLUG_TO_PAGE = { '': '', }; /* 增加主页面的题目和形容 */ const PAGE_TITLE = ''; const PAGE_DESCRIPTION = ''; /* 能够抉择显示的字体 https://fonts.google.com 例如:const GOOGLE_FONT = 'Noto Sans Simplified Chinese';*/ const GOOGLE_FONT = ''; /* 增加自定义脚本,能够增加Google Analytics */ const CUSTOM_SCRIPT = ``; /* CONFIGURATION ENDS HERE */ const PAGE_TO_SLUG = {}; const slugs = []; const pages = []; Object.keys(SLUG_TO_PAGE).forEach(slug => { const page = SLUG_TO_PAGE[slug]; slugs.push(slug); pages.push(page); PAGE_TO_SLUG[page] = slug; }); addEventListener('fetch', event => { event.respondWith(fetchAndApply(event.request)); }); function generateSitemap() { let sitemap = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'; slugs.forEach( (slug) => (sitemap += '<url><loc>https://' + MY_DOMAIN + '/' + slug + '</loc></url>') ); sitemap += '</urlset>'; return sitemap; } const corsHeaders = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, HEAD, POST, PUT, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type', }; function handleOptions(request) { if (request.headers.get('Origin') !== null && request.headers.get('Access-Control-Request-Method') !== null && request.headers.get('Access-Control-Request-Headers') !== null) { // Handle CORS pre-flight request. return new Response(null, { headers: corsHeaders }); } else { // Handle standard OPTIONS request. return new Response(null, { headers: { 'Allow': 'GET, HEAD, POST, PUT, OPTIONS', } }); } } async function fetchAndApply(request) { if (request.method === 'OPTIONS') { return handleOptions(request); } let url = new URL(request.url); url.hostname = 'www.notion.so'; if (url.pathname === '/robots.txt') { return new Response('Sitemap: https://' + MY_DOMAIN + '/sitemap.xml'); } if (url.pathname === '/sitemap.xml') { let response = new Response(generateSitemap()); response.headers.set('content-type', 'application/xml'); return response; } let response; if (url.pathname.startsWith('/app') && url.pathname.endsWith('js')) { response = await fetch(url.toString()); let body = await response.text(); response = new Response(body.replace(/www.notion.so/g, MY_DOMAIN).replace(/notion.so/g, MY_DOMAIN), response); response.headers.set('Content-Type', 'application/x-javascript'); return response; } else if ((url.pathname.startsWith('/api'))) { // Forward API response = await fetch(url.toString(), { body: url.pathname.startsWith('/api/v3/getPublicPageData') ? null : request.body, headers: { 'content-type': 'application/json;charset=UTF-8', 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36' }, method: 'POST', }); response = new Response(response.body, response); response.headers.set('Access-Control-Allow-Origin', '*'); return response; } else if (slugs.indexOf(url.pathname.slice(1)) > -1) { const pageId = SLUG_TO_PAGE[url.pathname.slice(1)]; return Response.redirect('https://' + MY_DOMAIN + '/' + pageId, 301); } else { response = await fetch(url.toString(), { body: request.body, headers: request.headers, method: request.method, }); response = new Response(response.body, response); response.headers.delete('Content-Security-Policy'); response.headers.delete('X-Content-Security-Policy'); } return appendJavascript(response, SLUG_TO_PAGE); } class MetaRewriter { element(element) { if (PAGE_TITLE !== '') { if (element.getAttribute('property') === 'og:title' || element.getAttribute('name') === 'twitter:title') { element.setAttribute('content', PAGE_TITLE); } if (element.tagName === 'title') { element.setInnerContent(PAGE_TITLE); } } if (PAGE_DESCRIPTION !== '') { if (element.getAttribute('name') === 'description' || element.getAttribute('property') === 'og:description' || element.getAttribute('name') === 'twitter:description') { element.setAttribute('content', PAGE_DESCRIPTION); } } if (element.getAttribute('property') === 'og:url' || element.getAttribute('name') === 'twitter:url') { element.setAttribute('content', MY_DOMAIN); } if (element.getAttribute('name') === 'apple-itunes-app') { element.remove(); } } } class HeadRewriter { element(element) { if (GOOGLE_FONT !== '') { element.append(`<link href="https://fonts.googleapis.com/css?family=${GOOGLE_FONT.replace(' ', '+')}:Regular,Bold,Italic&display=swap" rel="stylesheet"> <style>* { font-family: "${GOOGLE_FONT}" !important; }</style>`, { html: true }); } element.append(`<style> div.notion-topbar > div > div:nth-child(3) { display: none !important; } div.notion-topbar > div > div:nth-child(4) { display: none !important; } div.notion-topbar > div > div:nth-child(5) { display: none !important; } div.notion-topbar > div > div:nth-child(6) { display: none !important; } div.notion-topbar-mobile > div:nth-child(3) { display: none !important; } div.notion-topbar-mobile > div:nth-child(4) { display: none !important; } div.notion-topbar > div > div:nth-child(1n).toggle-mode { display: block !important; } div.notion-topbar-mobile > div:nth-child(1n).toggle-mode { display: block !important; } </style>`, { html: true }) } } class BodyRewriter { constructor(SLUG_TO_PAGE) { this.SLUG_TO_PAGE = SLUG_TO_PAGE; } element(element) { element.append(`<div style="display:none">Powered by <a href="http://fruitionsite.com">Fruition</a></div> <script> window.CONFIG.domainBaseUrl = 'https://${MY_DOMAIN}'; const SLUG_TO_PAGE = ${JSON.stringify(this.SLUG_TO_PAGE)}; const PAGE_TO_SLUG = {}; const slugs = []; const pages = []; const el = document.createElement('div'); let redirected = false; Object.keys(SLUG_TO_PAGE).forEach(slug => { const page = SLUG_TO_PAGE[slug]; slugs.push(slug); pages.push(page); PAGE_TO_SLUG[page] = slug; }); function getPage() { return location.pathname.slice(-32); } function getSlug() { return location.pathname.slice(1); } function updateSlug() { const slug = PAGE_TO_SLUG[getPage()]; if (slug != null) { history.replaceState(history.state, '', '/' + slug); } } function onDark() { el.innerHTML = '<div title="Change to Light Mode" style="margin-left: auto; margin-right: 14px; min-width: 0px;"><div role="button" tabindex="0" style="user-select: none; transition: background 120ms ease-in 0s; cursor: pointer; border-radius: 44px;"><div style="display: flex; flex-shrink: 0; height: 14px; width: 26px; border-radius: 44px; padding: 2px; box-sizing: content-box; background: rgb(46, 170, 220); transition: background 200ms ease 0s, box-shadow 200ms ease 0s;"><div style="width: 14px; height: 14px; border-radius: 44px; background: white; transition: transform 200ms ease-out 0s, background 200ms ease-out 0s; transform: translateX(12px) translateY(0px);"></div></div></div></div>'; document.body.classList.add('dark'); __console.environment.ThemeStore.setState({ mode: 'dark' }); }; function onLight() { el.innerHTML = '<div title="Change to Dark Mode" style="margin-left: auto; margin-right: 14px; min-width: 0px;"><div role="button" tabindex="0" style="user-select: none; transition: background 120ms ease-in 0s; cursor: pointer; border-radius: 44px;"><div style="display: flex; flex-shrink: 0; height: 14px; width: 26px; border-radius: 44px; padding: 2px; box-sizing: content-box; background: rgba(135, 131, 120, 0.3); transition: background 200ms ease 0s, box-shadow 200ms ease 0s;"><div style="width: 14px; height: 14px; border-radius: 44px; background: white; transition: transform 200ms ease-out 0s, background 200ms ease-out 0s; transform: translateX(0px) translateY(0px);"></div></div></div></div>'; document.body.classList.remove('dark'); __console.environment.ThemeStore.setState({ mode: 'light' }); } function toggle() { if (document.body.classList.contains('dark')) { onLight(); } else { onDark(); } } function addDarkModeButton(device) { const nav = device === 'web' ? document.querySelector('.notion-topbar').firstChild : document.querySelector('.notion-topbar-mobile'); el.className = 'toggle-mode'; el.addEventListener('click', toggle); nav.appendChild(el); onLight(); } const observer = new MutationObserver(function() { if (redirected) return; const nav = document.querySelector('.notion-topbar'); const mobileNav = document.querySelector('.notion-topbar-mobile'); if (nav && nav.firstChild && nav.firstChild.firstChild || mobileNav && mobileNav.firstChild) { redirected = true; updateSlug(); addDarkModeButton(nav ? 'web' : 'mobile'); const onpopstate = window.onpopstate; window.onpopstate = function() { if (slugs.includes(getSlug())) { const page = SLUG_TO_PAGE[getSlug()]; if (page) { history.replaceState(history.state, 'bypass', '/' + page); } } onpopstate.apply(this, [].slice.call(arguments)); updateSlug(); }; } }); observer.observe(document.querySelector('#notion-app'), { childList: true, subtree: true, }); const replaceState = window.history.replaceState; window.history.replaceState = function(state) { if (arguments[1] !== 'bypass' && slugs.includes(getSlug())) return; return replaceState.apply(window.history, arguments); }; const pushState = window.history.pushState; window.history.pushState = function(state) { const dest = new URL(location.protocol + location.host + arguments[2]); const id = dest.pathname.slice(-32); if (pages.includes(id)) { arguments[2] = '/' + PAGE_TO_SLUG[id]; } return pushState.apply(window.history, arguments); }; const open = window.XMLHttpRequest.prototype.open; window.XMLHttpRequest.prototype.open = function() { arguments[1] = arguments[1].replace('${MY_DOMAIN}', 'www.notion.so'); return open.apply(this, [].slice.call(arguments)); }; </script>${CUSTOM_SCRIPT}`, { html: true }); } } async function appendJavascript(res, SLUG_TO_PAGE) { return new HTMLRewriter() .on('title', new MetaRewriter()) .on('meta', new MetaRewriter()) .on('head', new HeadRewriter()) .on('body', new BodyRewriter(SLUG_TO_PAGE)) .transform(res); }配置对应的路由,也就是拜访咱们的域名后,须要执行咱们定义的notion worker ...

September 16, 2021 · 5 min · jiezi

关于博客搭建:Mac-OS上搭建Hexo博客流程

Hexo 介绍https://hexo.iohttps://hexo.io/zh-cn/环境筹备装置nodejs下载地址:https://nodejs.org/en/以:node-v14.17.1.pkg 为例 关上终端,切换root用户比方:关上terminal或者iterms终端软件,执行以下命令 //切换到root用户sudo su 装置淘宝镜像//应用npm装置相干依赖包,速度很慢,倡议装置淘宝镜像,后续命令应用cnpmnpm install -g cnpm --registry=https://registry.npm.taobao.org 装置Hexo//装置hexocnpm install -g hexo-cli Hexo装置胜利 初始化博客网站新建我的项目文件夹,并进入文件夹内比方:Blog。后续如果我的项目呈现问题,或者想从新创立,只须要删除此文件夹,即可 //初始化我的项目(必须进入到我的项目文件夹外面后,执行此命令)sudo hexo init 启动hexo//启动hexohexo s 浏览器关上博客网站// 浏览器关上http://localhost:4000 创立博客,并写博客Vim命令的应用,能够参考这里 //创立文章hexo n "我的第一篇博客文章" //编辑文章vim 我的第一篇博客文章.md 项目管理执行清理我的项目缓存新增博客文章或者批改博客文章内容,须要执行此命令 // 清理之前生成的网站hexo clean 从新生成我的项目// 从新生成博客我的项目hexo g 再次启动我的项目// 再次启动博客网站hexo s 批改主题抉择主题大家能够依照本人的须要下载适宜的主题。能够从官网下载比方:抉择 butterfly 下载主题代码在我的项目根目录下,即"Blog“文件夹下执行以下命令, // clone主题代码到 themes/butterflygit clone https://github.com/jerryc127/hexo-theme-butterfly.git themes/butterfly 批改我的项目配置文件,配置主题// 批改配置文件,主题主题vim _config.yml ...

June 28, 2021 · 1 min · jiezi

关于博客搭建:实战丨Halo轻松部署属于自己的博客系统

背景Halo 是一款现代化的集体独立博客零碎,给习惯写博客的同学多一个抉择。 云托管(Tencent CloudBase Run)是 云开发(Tencent CloudBase,TCB)提供的新一代云原生利用引擎(App Engine 2.0),反对托管任意容器化利用。 应用云托管部署博客零碎筹备工作开明 CloudBase 云开发环境留神: 包年包月环境无奈开明云托管。起源为“微信小程序”的环境暂不反对开明云托管。第 1 步:开明登录 云开发 CloudBase 控制台,抉择一个环境,进入云托管治理页面,单击「立刻开明」。 第 2 步:配置云托管所在地区云托管以后仅凋谢上海地区,更多地区将陆续凋谢。 云托管网络网络设置包含 公有网络 VPC 和 子网。以环境为维度,云托管中创立的所有服务,都将部署在这同一个 VPC 之中,且胜利开明云托管后不反对更换网络设置。 网络设置分为如下两种模式: 零碎默认配置云托管将为您主动新建一个 VPC 和子网,并将其绑定您以后的云开发环境。 后续您在以后环境下的云托管中创立的所有服务,都将被部署到这个 VPC 和子网中。 此过程无需您手动进行任何设置。后续您能够在 公有网络控制台 中查看并治理这个由云托管主动创立的 VPC 及子网,也能够将更多云资源(例如云服务器,云数据库等)部署在这个 VPC 之内,以便这些云资源进行互动。 自定义配置如果您之前曾经创立过公有网络 VPC 和子网,并在其中曾经部署有其余云资源(例如云服务器、云数据库等),且须要您的云托管利用与这些已存在的云资源进行互动,则您能够抉择「自定义配置」,而后抉择具体的 VPC 和子网。 VPC 只能抉择一个,子网反对抉择多个。 开明胜利单击「提交」,状态变为开明中,请期待数秒。 开明胜利后,您将主动跳转到云托管的服务列表页面。 至此您曾经胜利开明后云托管服务,您能够单击「新建服务」开始部署咱们的管理系统。 新建服务单击「新建服务」,填写服务名称、备注信息(选填)后,单击「提交」 封装halo博客零碎压缩包1、下载拉取halo博客零碎halo博客零碎:https://github.com/halo-dev/halo 依据状况批改mysql 和 redis等配置2、本地打包jar应用intellij idea 、eclipse 等工具打包工程。 若依属于多模块的我的项目,java的话,间接用生成的jar包 来做dockerfile吧。编译走本地,这样会不便点。PS:因为Java须要很多依赖,很多开发者习惯拉取到本地之类的。3、编写dockerfile文件# Use java 8 FROM java:8ADD target/*.jar /app.jar# 裸露端口EXPOSE 80ENTRYPOINT ["java","-jar","/app.jar"]4、文件夹或zip文件构造 ...

February 3, 2021 · 1 min · jiezi