<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>前端 on Docs</title><link>https://hiraethecho.github.io/docs/dev/frontend/</link><description>Recent content in 前端 on Docs</description><generator>Hugo --0.165.0</generator><language>en</language><managingEditor>wyz2016zxc@outlook.com(Hiraeth)</managingEditor><webMaster>wyz2016zxc@outlook.com(Hiraeth)</webMaster><atom:link href="https://hiraethecho.github.io/docs/dev/frontend/index.xml" rel="self" type="application/rss+xml"/><item><title>hugo</title><link>https://hiraethecho.github.io/docs/dev/frontend/hugo/</link><pubDate>Tue, 02 Dec 2025 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/dev/frontend/hugo/</guid><description>自制hugo主题后做一些记录</description><content:encoded><![CDATA[<h1 id="hugo">
  <a class="anchor inpage" href="#hugo">#</a>hugo</h1>
<p>hugo is a SSG. Using golang.</p>
<h2 id="hugo-site-structure">
  <a class="anchor inpage" href="#hugo-site-structure">##</a>hugo site structure</h2>
<h3 id="kinds">
  <a class="anchor inpage" href="#kinds">###</a>kinds</h3>
<p>There are mainly two kinds of site pages:</p>
<ul>
<li><code>page</code> for all markdown files like <code>content/subfolder/something.md</code> and goes to <code>https://example.com/subfolder/somethinng</code></li>
<li><code>section</code> for all <code>_index.md</code> in folder <code>content/another/_index.md</code> and goes to <code>https://example.com/another</code></li>
</ul>
<p>there are some special <code>section</code>, for example <code>content/_index</code> is <code>home</code>. And <code>taxonomy</code>, <code>term</code>, which are associated to taxonomy feature of hugo.</p>
<p>also you can make a bundle of a <code>page</code> with some resources. For example, <code>content/subfolder/something/index.md</code> goes to <code>https://example.com/subfolder/something</code>, and corresponding resources at <code>content/cubfolder/something/pic.jpg</code></p>
<h2 id="hugo-theme-structure">
  <a class="anchor inpage" href="#hugo-theme-structure">##</a>hugo theme structure</h2>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">custom-theme
├── assets
├── data
├── exampleSite
├── layouts
└── static</code><button type="button" class="copybtn">copy</button></pre></details><h3 id="layouts">
  <a class="anchor inpage" href="#layouts">###</a>layouts</h3>
<details open>
    <summary>tree</summary><pre
        class="codeblock"
      ><code class="language-tree" data-lang="tree">layouts
├── _markup
├── _partials
├── baseof.html
├── home.html
├── index.json
├── page.html
├── rss.xml
├── section.html
├── taxonomy.html
└── term.html</code><button type="button" class="copybtn">copy</button></pre></details><h3 id="render">
  <a class="anchor inpage" href="#render">###</a>render</h3>
<details open>
    <summary>tree</summary><pre
        class="codeblock"
      ><code class="language-tree" data-lang="tree">_markup
├── render-blockquote.html
├── render-codeblock-mermaid.html
├── render-codeblock.html
├── render-heading.html
├── render-image.html
└── render-link.html</code><button type="button" class="copybtn">copy</button></pre></details><h3 id="others">
  <a class="anchor inpage" href="#others">###</a>others</h3>
<p>assets</p>
<p>i18n</p>
<p>data</p>
<h2 id="go-templates">
  <a class="anchor inpage" href="#go-templates">##</a>go templates</h2>
<p>transforms data into HTML.</p>
<h3 id="context">
  <a class="anchor inpage" href="#context">###</a>context</h3>
<p>Hugo makes extensive use of the Go Template language for designing its themes. &ldquo;Context&rdquo; refers to the data that is passed to a template when it is rendered. Templates can access context to display dynamic content.</p>
<p><strong>Example Context Access:</strong></p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">&lt;title&gt;{{ .Title }}&lt;/title&gt;
&lt;p&gt;{{ .Content }}&lt;/p&gt;</code><button type="button" class="copybtn">copy</button></pre></details><h3 id="range-with-if-index">
  <a class="anchor inpage" href="#range-with-if-index">###</a>range, with, if, index</h3>
<ul>
<li><strong>Range</strong>: Used to iterate over collections such as a slice or map.
<strong>Example:</strong>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">{{ range .Data.Pages }}
  &lt;p&gt;{{ .Title }}&lt;/p&gt;
{{ end }}</code><button type="button" class="copybtn">copy</button></pre></details></li>
<li><strong>With</strong>: Equivalent to an <code>if</code> statement that changes the default context.
<strong>Example:</strong>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">{{ with .Site.Menu.main }}
  &lt;ul&gt;
    {{ range . }}
      &lt;li&gt;{{ .Name }}&lt;/li&gt;
    {{ end }}
  &lt;/ul&gt;
{{ end }}</code><button type="button" class="copybtn">copy</button></pre></details></li>
<li><strong>If</strong>: Conditional rendering.
<strong>Example:</strong>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">{{ if isset .Site.Params &#34;author&#34; }}
  &lt;p&gt;Author: {{ .Site.Params.author }}&lt;/p&gt;
{{ end }}</code><button type="button" class="copybtn">copy</button></pre></details></li>
<li><strong>Index</strong>: Retrieves specific content from a slice or map.
<strong>Example:</strong>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">{{ index .Site.Params &#34;social&#34; &#34;twitter&#34; }}</code><button type="button" class="copybtn">copy</button></pre></details></li>
</ul>
<p>Sorting, grouping, and accessing the first elements of collections can refine the data display.</p>
<h3 id="partials">
  <a class="anchor inpage" href="#partials">###</a>partials</h3>
<details open>
    <summary>go</summary><pre
        class="chroma codeblock"
      ><code class="language-go" data-lang="go"
          ><span style="display:flex;"><span>{{ <span style="color:#a6e22e">partial</span> <span style="color:#e6db74">&#34;header.html&#34;</span> . }}</span></span></code
        ><button type="button" class="copybtn">copy</button></pre></details><p>where <code>layouts/partials/header.html</code> is the partial template file.</p>
<h3 id="hugo-special">
  <a class="anchor inpage" href="#hugo-special">###</a>hugo special</h3>
<h4 id="slice-scratch">
  <a class="anchor inpage" href="#slice-scratch">####</a>slice, scratch</h4>
<p>Hugo provides a <code>slice</code> function that helps in working with lists and arrays, enabling you to append items or create slices dynamically. The <code>scratch</code> object in Hugo allows for temporary data storage and manipulation during template rendering through methods like <code>add</code>, <code>set</code>, and <code>get</code>.</p>
<p><strong>Example of Using Slice:</strong></p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">{{ $list := slice &#34;apple&#34; &#34;banana&#34; &#34;cherry&#34; }}
{{ range $list }}
  &lt;p&gt;{{ . }}&lt;/p&gt;
{{ end }}</code><button type="button" class="copybtn">copy</button></pre></details><p><strong>Example of Using Scratch:</strong></p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">{{ .Scratch.Set &#34;count&#34; 0 }}
{{ range .Pages }}
    {{ .Scratch.Add &#34;count&#34; 1 }}
{{ end }}
&lt;p&gt;Total Pages: {{ .Scratch.Get &#34;count&#34; }}&lt;/p&gt;</code><button type="button" class="copybtn">copy</button></pre></details><h2 id="hugo-feature">
  <a class="anchor inpage" href="#hugo-feature">##</a>hugo feature</h2>
<h3 id="taxonomies">
  <a class="anchor inpage" href="#taxonomies">###</a>taxonomies</h3>
<h3 id="menus">
  <a class="anchor inpage" href="#menus">###</a>menus</h3>
<h3 id="outputs">
  <a class="anchor inpage" href="#outputs">###</a>outputs</h3>
<h3 id="assets">
  <a class="anchor inpage" href="#assets">###</a>assets</h3>
<p>The <code>assets</code> folder in Hugo is a central place for managing your static assets, such as CSS, JavaScript, and images. You can preprocess your assets using Hugo Pipes, enabling features like minification, fingerprinting, and transpiling. This allows you to optimize your site&rsquo;s performance and maintain organized asset management.</p>
<p><strong>Example of Minification Using Hugo Pipes:</strong></p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">{{ $styles := resources.Get &#34;css/styles.css&#34; | minify }}
&lt;link rel=&#34;stylesheet&#34; href=&#34;{{ $styles.Permalink }}&#34;&gt;</code><button type="button" class="copybtn">copy</button></pre></details><p><strong>Example of Fingerprinting for Cache Busting:</strong></p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">{{ $js := resources.Get &#34;js/script.js&#34; | fingerprint }}
&lt;script src=&#34;{{ $js.Permalink }}&#34;&gt;&lt;/script&gt;</code><button type="button" class="copybtn">copy</button></pre></details><h3 id="misc">
  <a class="anchor inpage" href="#misc">###</a>misc</h3>
<p>i18n</p>
<h2 id="trick">
  <a class="anchor inpage" href="#trick">##</a>trick</h2>
<h3 id="backlinks">
  <a class="anchor inpage" href="#backlinks">###</a>backlinks</h3>
<h3 id="local-partials">
  <a class="anchor inpage" href="#local-partials">###</a>local partials</h3>
<h3 id="misc-1">
  <a class="anchor inpage" href="#misc-1">###</a>misc</h3>
<p>related</p>
<p>prev next</p>
]]></content:encoded></item><item><title>caldav协议</title><link>https://hiraethecho.github.io/docs/dev/frontend/caldav/</link><pubDate>Mon, 30 Jun 2025 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/dev/frontend/caldav/</guid><description>caldav是一个基于webdav的日历协议，可以用来同步日历数据。它是一个开放的标准，允许不同的日历应用程序和服务之间进行互操作。</description><content:encoded><![CDATA[<h1 id="caldav">
  <a class="anchor inpage" href="#caldav">#</a>Caldav</h1>
<h2 id="caldav-1">
  <a class="anchor inpage" href="#caldav-1">##</a>caldav</h2>
<p>caldav是一个基于webdav的日历协议，可以用来同步日历数据。它是一个开放的标准，允许不同的日历应用程序和服务之间进行互操作。</p>
<p>包括calendar、todo、event等。</p>
<h2 id="manage">
  <a class="anchor inpage" href="#manage">##</a>manage</h2>
<h3 id="todoman">
  <a class="anchor inpage" href="#todoman">###</a>todoman</h3>
<h3 id="khal">
  <a class="anchor inpage" href="#khal">###</a>khal</h3>
<h3 id="apple">
  <a class="anchor inpage" href="#apple">###</a>apple</h3>
<p>原生日历和提醒事项应用程序可以通过CalDAV协议与服务器进行同步。</p>
<h2 id="host-a-caldav">
  <a class="anchor inpage" href="#host-a-caldav">##</a>host a caldav</h2>
<h3 id="radicale">
  <a class="anchor inpage" href="#radicale">###</a>radicale</h3>
<h4 id="install-and-configurations">
  <a class="anchor inpage" href="#install-and-configurations">####</a>Install and configurations</h4>
<p>ref: 
:</p>
<p>Install radicale: 建议用包管理器安装，可以帮助解决依赖，以及创建<code>radicale</code>用户、创建文件夹之类的杂事。比如</p>
<details open>
    <summary>sh</summary><pre
        class="chroma codeblock"
      ><code class="language-sh" data-lang="sh"
          ><span style="display:flex;"><span>sudo dnf install radicale</span></span></code
        ><button type="button" class="copybtn">copy</button></pre></details><p>configurations:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang=""># /etc/radicale/config

[server]
hosts = [::]:5242, 0.0.0.0:5242 # ipv6, ipv4的host，从任何ip地址都可以访问
# hosts = localhost:5242 # 只允许本地地址访问
[auth]
type = htpasswd
htpasswd_encryption = autodetect
htpasswd_filename = /etc/radicale/users
[storage]
filesystem_folder = /var/lib/radicale/collections</code><button type="button" class="copybtn">copy</button></pre></details><p>set a user and passwd:</p>
<details open>
    <summary>shell</summary><pre
        class="chroma codeblock"
      ><code class="language-shell" data-lang="shell"
          ><span style="display:flex;"><span>htpasswd -5 -c /path/to/users user1</span></span></code
        ><button type="button" class="copybtn">copy</button></pre></details><p>Start as a systemd service:</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang=""># /etc/systemd/system/radicale.service
[Unit]
Description=A simple CalDAV (calendar) and CardDAV (contact) server
After=network.target
Requires=network.target

[Service]
ExecStart=/usr/bin/radicale --config /etc/radicale/confif
Restart=on-failure
User=radicale
# Deny other users access to the calendar data
UMask=0027
# Optional security settings
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
PrivateDevices=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
NoNewPrivileges=true
ReadWritePaths=/var/lib/radicale/ /var/cache/radicale/

[Install]
WantedBy=multi-user.target</code><button type="button" class="copybtn">copy</button></pre></details><p>这样在<code>http://localhost:5242/</code>就可以访问web页面，可以创建collection等。</p>
<h4 id="host">
  <a class="anchor inpage" href="#host">####</a>host</h4>
<p>用<code>cloudflare</code>的zero trust - network - tunnel来将radicale服务暴露到公网。记得选https。</p>
<h3 id="baikal">
  <a class="anchor inpage" href="#baikal">###</a>baikal</h3>
<h2 id="connect-a-caldav">
  <a class="anchor inpage" href="#connect-a-caldav">##</a>connect a caldav</h2>
<h3 id="from-linux">
  <a class="anchor inpage" href="#from-linux">###</a>from linux</h3>
<p>vdirsync</p>
<h3 id="from-apple-to-caldav-server">
  <a class="anchor inpage" href="#from-apple-to-caldav-server">###</a>from apple to caldav server</h3>
<h3 id="to-apple-caldav">
  <a class="anchor inpage" href="#to-apple-caldav">###</a>To apple caldav</h3>
<p>ref:</p>
<ul>
<li>
</li>
<li>
</li>
</ul>
<p>云上贵州服务器</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">https://&lt;server-id&gt;-caldav.icloud.com.cn/&lt;user-id&gt;/calendars/&lt;calendar-id&gt;/</code><button type="button" class="copybtn">copy</button></pre></details><p>在网页版icloud的日历界面打开开发者工具，然后找<code>Network</code>里的<code>Get</code>请求，过滤<code>XHR</code>，然后找类似 <code>https://&lt;server-id&gt;-calendarws.icloud.com.cn/ca/eventdetail/&lt;calendar-id&gt;/&lt;event-id&gt;?clientBuildNumber=&lt;some-random-text&gt;&amp;clientId=&lt;some-random-text&gt;&amp;clientMasteringNumber=&lt;some-random-text&gt;&amp;clientVersion=&lt;some-random-text&gt;&amp;dsid=&lt;user-id&gt;&amp;lang=&lt;some-random-text&gt;&amp;requestID=&lt;some-random-text&gt;&amp;usertz=&lt;some-random-text&gt;</code>的内容。</p>
<p>用 
 将<code>icloud</code>的日历同步到本地，以<code>.ics</code>格式存储。</p>
<details open>
    <summary>conf</summary><pre
        class="codeblock"
      ><code class="language-conf" data-lang="conf">[storage cal]
type = &#34;caldav&#34;
url = &#34;https://caldav.icloud.com/&#34;
username = &#34;...&#34;
password = &#34;...&#34;

[storage card]
type = &#34;carddav&#34;
url = &#34;https://contacts.icloud.com/&#34;
username = &#34;...&#34;
password = &#34;...&#34;</code><button type="button" class="copybtn">copy</button></pre></details><p>这里<code>username</code>就是用户名，而<code>password</code>是双重认证后再生成的app密码。服务器的话中国应该要<code>url = &quot;https://caldav.icloud.com.cn/&quot;</code></p>
<p>但是有两个问题：</p>
<ul>
<li>不支持<code>VTODO</code>格式，apple的提醒事项似乎不是这个协议。</li>
<li><code>icloud</code>如果有多个日历的话，标识id很长，难以记忆或使用，例如<code>87BBBA05-934B-4D5A-BB27-771A9CD413A2</code>。或者其中一个会被记为<code>home</code>，但是不知道什么规则。例如同步到<code>.local/share/calendars</code>后
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">~/.local/share/calendars
├── 87BBBA05-934B-4D5A-BB27-771A9CD413A2
└── home</code><button type="button" class="copybtn">copy</button></pre></details></li>
</ul>
]]></content:encoded></item><item><title>pake打包web应用</title><link>https://hiraethecho.github.io/docs/dev/frontend/pake/</link><pubDate>Sun, 08 Jun 2025 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/dev/frontend/pake/</guid><description>&lt;h1 id="pake打包web应用"&gt;
&lt;a class="anchor inpage" href="#pake%e6%89%93%e5%8c%85web%e5%ba%94%e7%94%a8"&gt;#&lt;/a&gt;pake打包web应用&lt;/h1&gt;
&lt;p&gt;
可以将web转化为桌面应用，比&lt;code&gt;electron&lt;/code&gt;更轻量。&lt;/p&gt;
&lt;h2 id="安装pake"&gt;
&lt;a class="anchor inpage" href="#%e5%ae%89%e8%a3%85pake"&gt;##&lt;/a&gt;安装pake&lt;/h2&gt;
&lt;p&gt;用户级安装：&lt;/p&gt;
&lt;details open&gt;
&lt;summary&gt;TEXT&lt;/summary&gt;&lt;pre
class="codeblock"
&gt;&lt;code class="language-" data-lang=""&gt;npm -g install pake-cli&lt;/code&gt;&lt;button type="button" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;&lt;p&gt;需要&lt;code&gt;rust&lt;/code&gt;等工具链&lt;/p&gt;
&lt;h2 id="打包web应用"&gt;
&lt;a class="anchor inpage" href="#%e6%89%93%e5%8c%85web%e5%ba%94%e7%94%a8"&gt;##&lt;/a&gt;打包web应用&lt;/h2&gt;
&lt;p&gt;例如&lt;/p&gt;
&lt;details open&gt;
&lt;summary&gt;TEXT&lt;/summary&gt;&lt;pre
class="codeblock"
&gt;&lt;code class="language-" data-lang=""&gt;pake chat.deepseek.com --name deepseek --width 1080 --height 1920 --show-system-tray --icon 512x512-RGBA.png&lt;/code&gt;&lt;button type="button" class="copybtn"&gt;copy&lt;/button&gt;&lt;/pre&gt;&lt;/details&gt;&lt;p&gt;要注意的是分辨率设置，以及icon格式为512x512的png，似乎必须是&lt;code&gt;RGBA&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;会得到&lt;code&gt;deepseek.deb&lt;/code&gt;，内部结构为&lt;/p&gt;</description><content:encoded><![CDATA[<h1 id="pake打包web应用">
  <a class="anchor inpage" href="#pake%e6%89%93%e5%8c%85web%e5%ba%94%e7%94%a8">#</a>pake打包web应用</h1>
<p>
可以将web转化为桌面应用，比<code>electron</code>更轻量。</p>
<h2 id="安装pake">
  <a class="anchor inpage" href="#%e5%ae%89%e8%a3%85pake">##</a>安装pake</h2>
<p>用户级安装：</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">npm -g install pake-cli</code><button type="button" class="copybtn">copy</button></pre></details><p>需要<code>rust</code>等工具链</p>
<h2 id="打包web应用">
  <a class="anchor inpage" href="#%e6%89%93%e5%8c%85web%e5%ba%94%e7%94%a8">##</a>打包web应用</h2>
<p>例如</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang="">pake chat.deepseek.com --name deepseek --width 1080 --height 1920 --show-system-tray --icon 512x512-RGBA.png</code><button type="button" class="copybtn">copy</button></pre></details><p>要注意的是分辨率设置，以及icon格式为512x512的png，似乎必须是<code>RGBA</code></p>
<p>会得到<code>deepseek.deb</code>，内部结构为</p>
<details open>
    <summary>deb</summary><pre
        class="codeblock"
      ><code class="language-deb" data-lang="deb">control.tar.gz
data.tar.gz
debian-binary</code><button type="button" class="copybtn">copy</button></pre></details><p>主要程序在<code>data.tar.gz</code>里面，用<code>tar -xvf data.tar.gz</code>得到</p>
<details open>
    <summary>usr</summary><pre
        class="codeblock"
      ><code class="language-usr" data-lang="usr"> usr
├──  bin
│   └──  pake
├──  lib
│   └──  deepseek
│       └──  png
│           └──  deepseek_512.png
└──  share
    ├──  applications
    │   └──  deepseek.desktop
    └──  icons
        └──  hicolor
            └──  512x512
                └──  apps
                    └──  pake.png</code><button type="button" class="copybtn">copy</button></pre></details><p>其中<code>usr/bin/pake</code>是单二进制文件，可以直接运行<code>./usr/bin/pake</code>。其他的是快捷方式<code>usr/share/application/deepseek.desktop</code>和图标等。</p>
<h2 id="on-arch">
  <a class="anchor inpage" href="#on-arch">##</a>On Arch</h2>
<p>在<code>archlinux</code>上可以将其做成<code>.zst</code>格式的包，用<code>pacman</code>管理。</p>
<p>把下面内容写入<code>PKGBUILD</code>文件</p>
<details open>
    <summary>TEXT</summary><pre
        class="codeblock"
      ><code class="language-" data-lang=""># Maintainer: hiraethecho &lt;wyz2016zxc at outlook dot com&gt;
pkgname=&#34;${_appname}-pake&#34;
pkgver=1.0.0
pkgrel=1
pkgdesc=&#34;${_appname} pake&#34;
arch=(&#39;x86_64&#39;)
license=(&#39;MIT&#39;)
conflicts=(&#34;${_appname}-pake&#34;)
depends=(
    &#39;gtk3&#39;
    &#39;webkit2gtk-4.1&#39;
)
source=(
  ${_appname}.deb
)
sha256sums=(&#39;SKIP&#39;)
prepare() {
    bsdtar -xf &#34;${srcdir}/data.&#34;*
    sed -e &#34;
        s/Exec=pake/Exec=${_appname}/g
        s|Icon=pake|Icon=${_appname}|g
    &#34; -i &#34;${srcdir}/usr/share/applications/${_appname}.desktop&#34;
    mv ${srcdir}/usr/share/icons/hicolor/*/apps/pake.png ${srcdir}/usr/share/icons/pake.png
}
package() {
    install -Dm755 &#34;${srcdir}/usr/bin/pake&#34; &#34;${pkgdir}/usr/bin/${_appname}&#34;
    install -Dm644 &#34;${srcdir}/usr/share/applications/${_appname}.desktop&#34; &#34;${pkgdir}/usr/share/applications/${_appname}.desktop&#34;
    install -Dm644 &#34;${srcdir}/usr/share/icons/pake.png&#34; &#34;${pkgdir}/usr/share/pixmaps/${_appname}.png&#34;
}</code><button type="button" class="copybtn">copy</button></pre></details><p>然后执行这个shell脚本，注意<code>-i</code> <code>-w</code> <code>-n</code>选项</p>
<details open>
    <summary>pake2zst</summary><pre
        class="codeblock"
      ><code class="language-pake2zst" data-lang="pake2zst">#!/usr/bin/bash
# generate a zst from pake
url=&#34;&#34;
icon=&#34;&#34;
name=&#34;&#34;
while getopts &#34;:n:i:w:&#34; opt; do
  case $opt in
  n) name=&#34;$OPTARG&#34; ;;
  i) icon=&#34;$OPTARG&#34; ;;
  w) url=&#34;$OPTARG&#34; ;;
  \?)
    echo &#34;无效选项: -$OPTARG&#34; &gt;&amp;2
    ;;
  esac
done

echo -e &#34;$url $icon $name&#34;
# pake $url --icon $icon --height=1080 --width=1920 --show-system-tray --name $appname
sed -i &#34;/pkgdesc/a\\url=${url}&#34; PKGBUILD
sed -i &#34;/pkgname/i\\_appname=${name}&#34; PKGBUILD
makepkg</code><button type="button" class="copybtn">copy</button></pre></details><p>这样就会生成一个<code>.zst</code>包，用<code>pacman -U name-pake-1.0.0-1-x86_64.pkg.tar.zst</code>即可。</p>
]]></content:encoded></item><item><title>用obsidian管理多个博客</title><link>https://hiraethecho.github.io/docs/dev/frontend/blogs/</link><pubDate>Sat, 05 Apr 2025 00:00:00 +0000</pubDate><author>wyz2016zxc@outlook.com(Hiraeth)</author><guid>https://hiraethecho.github.io/docs/dev/frontend/blogs/</guid><description>之前在一个obsidian仓库管理hexo hugo mkdocs三个网站的方法</description><content:encoded><![CDATA[<h1 id="用obsidian管理多个博客">
  <a class="anchor inpage" href="#%e7%94%a8obsidian%e7%ae%a1%e7%90%86%e5%a4%9a%e4%b8%aa%e5%8d%9a%e5%ae%a2">#</a>用obsidian管理多个博客</h1>
<p>一些花里胡哨的技巧。</p>
<h2 id="目标">
  <a class="anchor inpage" href="#%e7%9b%ae%e6%a0%87">##</a>目标</h2>
<p>多个博客网站，都用github pages功能发布。多个博客的post文件放在一个obsidian仓库中管理，并且本身作为一个github repository。push 这个obsidian/github仓库后将博客内容同步到其他博客repo。各个repo自己发布。</p>
<h2 id="思路">
  <a class="anchor inpage" href="#%e6%80%9d%e8%b7%af">##</a>思路</h2>
<p>用github action，push之后检测变化的文件，clone对应仓库，同步文件，再分别push。</p>
<p>需要注意的是，GitHub action对各个repo的读写权限，需要配置各种keys。<br>
先生成ssh keys，将pub放入博客repo的deploy key，记得打开写权限；private key放入obsidian repo的secrets中。<br>
每个博客仓库都需要一个密钥对。</p>
<h2 id="示例">
  <a class="anchor inpage" href="#%e7%a4%ba%e4%be%8b">##</a>示例</h2>
<p>例如将<code>obsidian/hexo</code>的内容同步到<code>hexo</code>框架下对应的<code>hexo/source/_posts</code>文件夹下，<code>/.github/workflows/sync_hexo</code>中</p>
<details open>
    <summary>yml</summary><pre
        class="chroma codeblock"
      ><code class="language-yml" data-lang="yml"
          ><span style="display:flex;"><span><span style="color:#f92672">name</span>: <span style="color:#ae81ff">Sync ob/hexo to hexo/source_posts</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">on</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">push</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">paths</span>:
</span></span><span style="display:flex;"><span>            - <span style="color:#e6db74">&#34;hexo/**&#34;</span> <span style="color:#75715e"># 监听文件夹内的文件变化，没有变化不会触发action</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">jobs</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">sync</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">runs-on</span>: <span style="color:#ae81ff">ubuntu-latest</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">steps</span>:
</span></span><span style="display:flex;"><span>            <span style="color:#75715e"># 检出 obsidian 仓库的代码</span>
</span></span><span style="display:flex;"><span>            - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">Checkout blogs repository</span>
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">uses</span>: <span style="color:#ae81ff">actions/checkout@v3</span>
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">with</span>:
</span></span><span style="display:flex;"><span>                  <span style="color:#f92672">repository</span>: <span style="color:#ae81ff">username/obsidian_repo</span>
</span></span><span style="display:flex;"><span>                  <span style="color:#f92672">path</span>: <span style="color:#ae81ff">obsidian</span>
</span></span><span style="display:flex;"><span>            - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">commit</span>
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">run</span>: |<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  cd obsidian
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  git log -1 --pretty=%B &gt; ~/commit</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>            <span style="color:#75715e"># 设置 Git 配置（用户名和ssh私钥）</span>
</span></span><span style="display:flex;"><span>            - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">Set up Git</span>
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">env</span>:
</span></span><span style="display:flex;"><span>                  <span style="color:#f92672">ACTIONS_KEY</span>: <span style="color:#ae81ff">${{ secrets.OB_PRI }}</span>
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">run</span>: |<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  mkdir -p ~/.ssh/
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  echo &#34;$ACTIONS_KEY&#34; &gt; ~/.ssh/id_rsa
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  chmod 700 ~/.ssh
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  chmod 600 ~/.ssh/id_rsa
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  ssh-keyscan github.com &gt;&gt; ~/.ssh/known_hosts
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  git config --global user.name &#34;action&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  git config --global user.email &#34;email&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  git config --global core.quotepath false
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  git config --global i18n.commitEncoding utf-8
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  git config --global i18n.logOutputEncoding utf-8</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>            - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">clone</span>
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">run</span>: |<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  git clone git@github.com:username/hexo_repo ~/hexo</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>            - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">Sync files from obsidian/hexo to hexo/source/_posts</span>
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">run</span>: |<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  rsync -av obsidian/hexo/ ~/hexo/source/_posts/</span>
</span></span><span style="display:flex;"><span>            - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">Commit and push changes to HexoBlog repository</span>
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">run</span>: |<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  cd ~/hexo
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  git add .
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  git commit -m &#34;Sync obsidian to hexo $(cat ~/commit)&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  git push origin main</span></span></span></code
        ><button type="button" class="copybtn">copy</button></pre></details><p>注意其中 <code>username</code> <code>hexo_repo</code> <code>obsidian_repo</code> <code>secrets.OB_PRI</code>等根据情况改写。</p>
]]></content:encoded></item></channel></rss>