arch theme optimization
2025-08-15

Switch Language

Switching language is supported by Arch, but after switch is clicked, you still have to choose which language to switch to. This is reasonable and understandable, but can be unnecessary when there are only two languages. So a slight change is made.

If there are only two languages in _config.yml, just switch to another language when switch is clicked. Otherwise, languages different from current language are displayed, and when a language is clicked, switch to that language.

Implement

Replace themes/arch/layout/_partial/switchlang.ejs with following content.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<% let currentPath = page.path && page.path.indexOf('/') >= 0 ? page.path.substr(page.path.indexOf('/')) : '' %>
<!-- filter lang different from page.lang -->
<% let otherLangs = config.language.filter((lang) => lang && lang !== 'default' && lang !== page.lang) %>
<div class="switchlang-icon tools-bar-item" title="Switch a language">
<% if (otherLangs.length === 1) { %>
<a class="lang-item" href="<%- url_for('/' + otherLangs[0] + currentPath) %>" title="<%- __(otherLangs[0]) %>">
<i class="icon-lang-switcher">
<svg t="1670338371149" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1377" width="16" height="16"><path d="M890.688 576h-124.672c-6.2912 100.928-27.264 192.7296-58.5216 266.5792 95.36-56.512 164.16-153.1072 183.1936-266.5792z m0-128c-19.0336-113.472-87.8336-210.0672-183.1936-266.5792 31.2512 73.856 52.2304 165.6576 58.528 266.5792h124.672zM133.312 448h124.672c6.2912-100.928 27.264-192.7296 58.5216-266.5792C221.1456 237.9328 152.3456 334.528 133.312 448z m0 128c19.0336 113.472 87.8336 210.0672 183.1936 266.5792-31.2512-73.856-52.2304-165.6576-58.528-266.5792H133.312z m504.416 0h-251.456c6.6944 93.6 27.8848 178.176 59.2 240.7936 16.0448 32.1088 33.4656 55.6416 49.5488 69.248 5.5488 4.6912 10.2336 7.6032 13.8688 9.088 1.7024 0.704 2.528 0.8704 3.1104 0.8704 0.576 0 1.408-0.1664 3.1104-0.864 3.6352-1.4912 8.32-4.4032 13.8688-9.0944 16.0832-13.6064 33.504-37.1392 49.5552-69.248 31.3088-62.6176 52.4992-147.1936 59.2-240.7936z m0-128c-6.6944-93.6-27.8848-178.176-59.2-240.7936-16.0448-32.1088-33.4656-55.6416-49.5488-69.248-5.5488-4.6912-10.2336-7.6032-13.8688-9.088-1.7024-0.704-2.528-0.8704-3.1104-0.8704-0.576 0-1.408 0.1664-3.1104 0.864-3.6352 1.4912-8.32 4.4032-13.8688 9.0944-16.0832 13.6064-33.504 37.1392-49.5552 69.248-31.3088 62.6176-52.4992 147.1936-59.2 240.7936h251.4624zM512 1024c-282.7712 0-512-229.2288-512-512S229.2288 0 512 0s512 229.2288 512 512-229.2288 512-512 512z" p-id="1378" fill="#666666"></path></svg>
</i>
</a>
<% } else if (otherLangs.length) { %>
<a href="javascript: void(0)" id="switchlang">
<i class="icon-lang-switcher">
<svg t="1670338371149" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1377" width="16" height="16"><path d="M890.688 576h-124.672c-6.2912 100.928-27.264 192.7296-58.5216 266.5792 95.36-56.512 164.16-153.1072 183.1936-266.5792z m0-128c-19.0336-113.472-87.8336-210.0672-183.1936-266.5792 31.2512 73.856 52.2304 165.6576 58.528 266.5792h124.672zM133.312 448h124.672c6.2912-100.928 27.264-192.7296 58.5216-266.5792C221.1456 237.9328 152.3456 334.528 133.312 448z m0 128c19.0336 113.472 87.8336 210.0672 183.1936 266.5792-31.2512-73.856-52.2304-165.6576-58.528-266.5792H133.312z m504.416 0h-251.456c6.6944 93.6 27.8848 178.176 59.2 240.7936 16.0448 32.1088 33.4656 55.6416 49.5488 69.248 5.5488 4.6912 10.2336 7.6032 13.8688 9.088 1.7024 0.704 2.528 0.8704 3.1104 0.8704 0.576 0 1.408-0.1664 3.1104-0.864 3.6352-1.4912 8.32-4.4032 13.8688-9.0944 16.0832-13.6064 33.504-37.1392 49.5552-69.248 31.3088-62.6176 52.4992-147.1936 59.2-240.7936z m0-128c-6.6944-93.6-27.8848-178.176-59.2-240.7936-16.0448-32.1088-33.4656-55.6416-49.5488-69.248-5.5488-4.6912-10.2336-7.6032-13.8688-9.088-1.7024-0.704-2.528-0.8704-3.1104-0.8704-0.576 0-1.408 0.1664-3.1104 0.864-3.6352 1.4912-8.32 4.4032-13.8688 9.0944-16.0832 13.6064-33.504 37.1392-49.5552 69.248-31.3088 62.6176-52.4992 147.1936-59.2 240.7936h251.4624zM512 1024c-282.7712 0-512-229.2288-512-512S229.2288 0 512 0s512 229.2288 512 512-229.2288 512-512 512z" p-id="1378" fill="#666666"></path></svg>
</i>
</a>
<div class="switchlang-content hidden">
<% otherLangs.forEach(function(item) { %>
<a class="lang-item" href="<%- url_for('/' + item + currentPath) %>" title="<%- item %>">
<%= __(item) %>
</a>
<% }) %>
</div>
<%- js(['/js/switchlang.js']) %>
<% } %>
</div>
switch-lang

Translate Tip

Translate tip is not a built-in feature of Arch. Changes have to made to make it work.

If post or page is translated from another language, use origin_lang: xxx in front matter to show the translate tip which guides user to the original page.

Usage

1
2
3
4
5
6
7
---
title: online 404 error troubleshooting
date: 2025-07-27 17:41:21
lang: en
origin_lang: zh-CN
sticky: 2
---
translate-tip

Implement

First, add translation to theme/arch/languages/[lang].yml.

1
2
3
# themes/arch/languages/en.yml
TranslateTip: This page was translated by AI and proofread by humans. You may want to
OriginTip: view in original language.
1
2
3
# themes/arch/languages/zh-CN.yml
TranslateTip: 该页面由AI翻译并经过人工校对,你可能想要
OriginTip: 查看原文

Second, add following code to <div class="markdown-body"> in theme/arch/layout/post.ejs.

1
2
3
4
5
6
7
8
9
10
<!-- add translate tip and navigate to original language -->
<% if (page.origin_lang && page.origin_lang !== page.lang) { %>
<% let currentPath = page.path && page.path.indexOf('/') >= 0 ? page.path.substr(page.path.indexOf('/')) : '' %>
<blockquote>
<p>
<%- __('TranslateTip') %>
<a href="<%- url_for('/' + page.origin_lang + currentPath) %>"><%- __('OriginTip') %></a>
</p>
</blockquote>
<% } %>

I add it to /about page and all post.

translate-tip-imp1

Search is supported in Arch, if you want to use it, just following usage below to enable it.

However, I find there are still some improvements can be made.

  1. When search icon is clicked, search input is not focused, and user have to click input to activate getSearchFile.
  2. Event listener can be added to improve UX, for example, when / is clicked, open search modal and focus search input; when ESC is clicked, close search modal.

So I make some changes to search.ejs to implement these improvements. If you're fine with these little defects, changes below is not necessary for you.

Usage

1
2
3
4
5
6
# _config.yml
# https://github.com/wzpan/hexo-generator-search
search:
path: search.xml
field: all
content: true
1
2
3
4
5
# _config.arch.yml
# Article Content Search / 文章搜索
search:
enable: true
placeholder: search...

Improvement

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// themes/arch/layout/_partial/search.ejs
let isSearchFirst = true;
inputArea.onclick = function () {
doSearchFileOnce()
}

// only searchFile once
function doSearchFileOnce() {
if (isSearchFirst) {
getSearchFile()
isSearchFirst = false;
}
}

function openOrHideSearchContent() {
let isHidden = searchOverlayArea.classList.contains('hidden')
if (isHidden) {
searchOverlayArea.classList.remove('hidden')
document.body.classList.add('hidden')
setTimeout(() => {
// auto focus and doSearchFile
inputArea.focus()
doSearchFileOnce()
}, 100);
} else {
searchOverlayArea.classList.add('hidden')
document.body.classList.remove('hidden')
}
}

document.addEventListener('keydown', function (event) {
// if the search content is open, pressing ESC will close it
if (event.keyCode === 27 && !searchOverlayArea.classList.contains('hidden')) {
openOrHideSearchContent()
return;
}
// if the search content is closed, pressing '/' will open it and focus on the input and build search index
if (event.keyCode === 191 && searchOverlayArea.classList.contains('hidden')) {
openOrHideSearchContent()
}
}, false);

search-diff-1 search-diff-2

Pin

Pin is supported in Arch, but doesn't work. Make sure you use sticky: xxx in front matter and modify item.top to item.sticky in theme/arch/layout/index.ejs.

sticky

Usage

1
2
3
4
5
6
7
---
title: online 404 error troubleshooting
date: 2025-07-27 17:41:21
lang: en
origin_lang: zh-CN
sticky: 2
---