我使用的主题是chic
修改主题markdown的高亮代码
我当前使用的主题是不支持jsx
的,所以对于react
代码不能友好支持。所以使用hexo-prism-plugin
修改了高亮部分
坑:
我安装了hexo-prism-plugin
之后发现还是无法高亮jsx
代码, 后来发现还要要安装hexo-inject
模块
npm install hexo-prism-plugin hexo-inject --save
- 修改
_config.yml
highlight:
enable: false # 关闭默认的highlight
prism_plugin:
mode: 'preprocess' # realtime/preprocess
theme: 'base16-ateliersulphurpool.light' # 主题
line_number: false # default false
# custom_css: 'path/to/your/custom.css'
为主题图片添加大图
主题无法对图片进行放大,图片最大也只是 780 * 562
, 体验上不是很好,这里我使用了fancybox 进行修改
下载fancybox的文件
将
jquery.fancybox.min.js
,jquery.min.js
放入theme/chic/source/js
目录下将
jquery.fancybox.min.css
放入theme/chic/source/css/_lib/
目录下修改
chic/_config.yml
, 添加代码fancybox: enable: true jquery: /js/jquery.min.js fancyjs: /js/jquery.fancybox.min.js
修改
Chic/layout/_partial/head.ejs
添加以下代码
<% if(theme.fancybox.enable!==null&&theme.fancybox.enable===true){ %>
<script type="text/javascript" src="<%- url_for(theme.fancybox.jquery) %>"></script>
<script type="text/javascript" src="<%- url_for(theme.fancybox.fancyjs) %>"></script>
<% } %>
- 在
Chic/source/css/style.styl
添加,
@import "_lib/jquery.fancybox.min.css"
这里添加css 不知道为什么不可以直接 跟上面添加js 一样,我找了很久都没找到解决方案,只能够在style 下强行添加css
- 最后在
source/js/script.js
的document.ready()的回调回调函数添加 以下代码就可以
$("a.group").fancybox({
'transitionIn' : 'elastic',
'transitionOut' : 'elastic',
'speedIn' : 600,
'speedOut' : 200,
'overlayShow' : false
});
使用
这里强行使用<a class="group">
链接 包裹这img 表示使用fancybox
<a class="group" rel="group1" href="图片url">
<img src="图片url" />
</a>
添加力扣页面
我这里是想自定义添加一个新的页面,主要放自己练习算法时的解题思路,叫力扣,但又不想跟原来发表的文章混在一起
- 添加文件夹
source/algorithm
, 只有一个文件index.md
# index.md
---
title: 力扣
date: 2020-04-08 16:09:43
layout: algorithm
---
- 在
Chic/layout
添加algorithm.ejs
<%- partial('_page/algorithm', {pagination: config.archive, index: true}) %>
- 在
Chic/layout/_page
添加algorithm.ejs
// Chic/layout/_page/algorithm.ejs
<div class="post-wrap algorithm-page archive">
<div class="tags-algorithm">
// 这里就是算法 tag, 我只筛选出 tag包含 algorithm- 的那些
<%site.tags.forEach(item=>{%>
<% if(item.name.includes("algorithm-")) { %>
<a class="tags-item" href="<%-url_for(item.path)%>"><%- item.name.split("algorithm-")[1] %><span class="nums"><%-item.length%></%-item.length%></span></%-></a>
<% } %>
<%})%> 1 < div> <div class=""archive">" 每页条数 <% var perpage="config.algorithm_generator.per_page" %> 这里我直接获取当前页面是第几页,没有page的话就是第一页 currentpage="url.match(/page\/(.*)\//)" ? url.match( page\ (.*)\ )[1] : last_year="'';" 然后我过滤掉 只是type="=" 'algorithm'的那些文章, 这个type, 在我们新键文章的时候跟title,tag那些写在一起 posts="site.posts.filter((item)" => item.type && 'algorithm') 做一个排序, 按最新的排 posts.data="posts.data.sort((a," b)=">" b.date - a.date) 选择当前页面的文章 posts.slice((currentpage 1) * perpage, ).each(function (post) { cur_year="post.date.year();" if(last_year !="=" cur_year){ <h3><%- %>< h3> } <article <a href=""<%-" url_for(post.path) %>"><%="post.title" a> <span date(post.date, theme.date_format) span> article> }) 分页 if(math.ceil(posts.length perpage) > <nav <%- paginator({ prev_next: false, end_size: 1, mid_size: 2, total: math.ceil(posts.length nav> div>< code></%})%>></%></%>
这里有个坑,我们点击 /algorithm/page/2
的时候会报当前页面存在,我通过 hexo-generator-category
找到类似的解决方案,
我通过文档的生成器写了一个类似的解决方案
- 在
Chic/script
下添加algorithm.js
, 这里为了搞一个分页出来而已
var pagination = require('hexo-pagination'); // 要安装模块啊
hexo.extend.generator.register('algorithm', function(locals){
// 这里不能对locals.post 进行更改,一旦发生更改,网站变量 site.posts 的内容也会跟着更改,这里不知道是为什么,我纠结了很久
let allPost = locals.posts;
return pagination('/algorithm', allPost, {
perPage: this.config.algorithm_generator.per_page, // 在 _config.yml 添加 algorithm_generator: 配置 类似 category_generator
layout: ['algorithm', 'archive', 'index'], // 如果algorith这个layout,没有就会用 archive, 如此类推
format: 'page' + '/%d/',
data: {
__index: true
}
});
});
- 最后只要修改一下
Chic/layout/_page/archive.ejs
文件跟上面类似第三部就行了, 这里说一下 config ,可以从最外层_config.yml
进行配置
文章搜索
- 先执行
npm install hexo-generator-search -s
, 这个插件是为了生成search.json
, 他包含的是文章的基本信息 - 然后就是写 html 和 css了,我这里使用的是模态框,所以可以根据form 表单提交后唤出modal,然后进行ajax对search.json进行查询.
- 我们根据关键字对文章content进行匹配,匹配有的加入数组,然后对匹配成功的那些数据进行字符截取,另外对关键字做highlight操作
配置 _config.yml
这里需要配置一下 root 下的 _config.yml
, 添加以下代码
# search
search:
enable: true
path: search.json
field: post
content: true
添加modal
我这里直接写在了Chic/layout/layout.ejs
, 我们只需要控制这个modal
的display
属性就好了
html
<!-- Chic/layout.ejs -->
<div id="u-search">
<div class="modal">
<div class="modal-header">
<div class="container">
<form id="u-search-modal-form" class="u-search-modal-form">
<button type="submit" class="form-submit-btn">
<img src="<%- url_for(theme.searchImg) %>" class="search-btn-img" />
</button>
<input placeholder="搜索文章。。。" class="form-input" id="modal-form-input">
</form>
<a class="modal-close">x</a>
</div>
<div class="search-loading">
<div class="search-loading-bar"></div>
</div>
</div>
<div class="modal-body">
<!-- ul 格式如下 -->
<!-- <ul class="modal-results">
<li class="result-item">
<a class="result-item-detail">
<span class="title">页面配置</span>
<span class="content">
content
</span>
</a>
</li>
</ul> -->
</div>
</div>
<div class="modal-overlay"></div>
</div>
modal 样式
我把他放在了Chic/source/css/_lib/search.css
这个要在 Chic\source\css\style.styl
引用,添加代码
@import "_lib/search.css"
点击查看样式,这里是search.css 代码
#u-search {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 60px 20px;
z-index: 1001;
}
#u-search .modal {
position: fixed;
height: 80%;
width: 100%;
max-width: 640px;
left: 50%;
top: 0;
margin: 64px 0px 0px -320px;
background: #fff;
z-index: 3;
border-radius: 4px;
overflow: hidden;
}
#u-search .modal-header {
position: relative;
width: 100%;
height: 64px;
z-index: 3;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
font-size: 16px;
box-shadow: 0 1px 2px 0px rgba(0,0,0,0.1);
background: #fff;
transition: all 0.28s ease;
-moz-transition: all 0.28s ease;
-webkit-transition: all 0.28s ease;
-o-transition: all 0.28s ease;
}
#u-search .modal-header .container{
display: flex;
flex-direction: row;
align-items: center;
padding: 0px;
}
#u-search .modal-header .container .u-search-modal-form {
display: flex;
flex-direction: row;
align-items: center;
flex: 1;
}
#u-search .u-search-modal-form .form-submit-btn {
width: 50px;
height: 64px;
background: none;
border: none;
outline: none;
margin: 0 5px 0 5px ;
}
#u-search .u-search-modal-form .form-submit-btn img {
width: 33px;
height: 33px;
}
#u-search .modal-header .container .u-search-modal-form .form-input {
flex: 1;
margin-right: 15px;
border: none;
padding: 10px 10px;
outline: none;
}
#u-search .modal-header .modal-close {
display: block;
width: 55px;
height: 64px;
top: 0;
right: 0;
color: #2196f3;
cursor: pointer;
text-align: center;
line-height: 64px;
vertical-align: middle;
transition: all 0.28s ease;
-moz-transition: all 0.28s ease;
-webkit-transition: all 0.28s ease;
-o-transition: all 0.28s ease;
z-index: 2;
font-size: 22px;
}
#u-search .modal-header .search-loading {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 2px;
background: transparent;
z-index: 1;
}
#u-search .modal-header .search-loading .search-loading-bar {
transition: all 0.28s ease;
-moz-transition: all 0.28s ease;
-webkit-transition: all 0.28s ease;
-o-transition: all 0.28s ease;
position: relative;
display: none;
width: 0%;
height: 100%;
background: #2196f3;
}
#u-search .modal .modal-body {
padding: 15px;
height: calc(100% - 85px);
overflow: auto;
}
#u-search .modal .modal-body::-webkit-scrollbar{
width: 5px;
height: 5px;
/**/
}
#u-search .modal .modal-body::-webkit-scrollbar-track{
background: rgb(239, 239, 239);
border-radius:2px;
}
#u-search .modal .modal-body::-webkit-scrollbar-thumb{
background: #bfbfbf;
border-radius:10px;
}
#u-search .modal .modal-body::-webkit-scrollbar-thumb:hover{
background: #333;
}
#u-search .modal .modal-body::-webkit-scrollbar-corner{
background: #179a16;
}
#u-search .modal .modal-body .modal-results {
list-style: none;
padding-left: 0;
margin: 0px;
}
#u-search .modal .modal-body .modal-results .result-item {
padding: 15px;
}
#u-search .modal .modal-body .modal-results .result-item:hover {
background: #e8f4fd;
}
#u-search .modal .modal-body .modal-results .result-item .result-item-detail {
display: flex;
flex-direction: column;
}
#u-search .modal .modal-body .modal-results .result-item .result-item-detail .title {
color: #6e6e6e;
font-weight: 700;
font-size: 18px;
margin-bottom: 10px;
}
#u-search .modal .modal-body .modal-results .result-item .result-item-detail .content {
display: block;
white-space: inherit;
word-break: break-all;
text-overflow: ellipsis;
font-size: 14px;
color: rgba(85,85,85,0.65);
letter-spacing: 1px;
user-select: none;
}
#u-search .search-keyword {
color: #0c7cd5;
text-decoration: underline;
font-weight: bold;
font-style:normal
}
#u-search .modal-body .no-result {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#u-search .modal-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.7);
z-index: 1;
}
@media screen and (max-width: 680px) {
#u-search {
padding: 0px;
display: none;
}
#u-search .modal {
box-shadow: none;
max-width: none;
top: 0;
left: 0;
margin: 0;
height: 100%;
border-radius: 0;
}
#u-search .modal-header {
border-radius: 0;
padding: 0px;
}
}
.modal-active {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
/* 以下是搜索框 */
.search {
margin-right: 6px;
display: flex;
flex-direction: row;
align-items: center;
}
.search .form-search {
padding: 10px 8px;
}
.search .form-search .input {
display: block;
line-height: 1.3;
color: #555;
background: #e8e8e8;
padding: 5px 8px;
box-shadow: none;
box-sizing: border-box;
font-size: 1rem;
border-radius: 8px;
border: none;
outline: none;
}
.search .search-btn {
width: 22px;
height: 22px;
line-height: 22px;
margin-right: 5px;
}
.search .search-btn .search-btn-img {
height: 100%;
width: 100%;
}
@media screen and (max-width: 479px) {
.navbar-mobile-right {
display: flex;
flex-direction: row;
align-items: center;
}
.search .search-btn {
cursor: pointer;
}
.search .form-search {
display: none;
}
.mobile-search {
position: absolute;
top: 0px;
left: 0px;
right: 50px;
padding-left: 15px;
background: #fff;
height: 80px;
display: flex;
flex-direction: row;
margin-right: 15px;
}
.mobile-search .form-search {
display: block;
flex: 1;
}
.mobile-search .input {
width: 100%;
}
}
增加搜索框
我把该文件放在了 Chic/layout/_partial/search.ejs
<% if(config.search && config.search.enable ) { %>
<div class="search ">
<div class="search-btn" onClick="searchToggle()">
<img src="<%- url_for(theme.searchImg) %>" class="search-btn-img" />
</div>
<form class="form-search">
<input class="input" placeholder="搜索文章" autocomplete="off" id="<%= name %>-search-input"/>
</form>
</div>
<% } %>
我们在 Chic\layout\_partial\header.ejs
添加这个搜索框, 要在pc的menu, 和mobile的menu添加,
<% var defaultName = 'pc' %>
<%- partial('_partial/search', { name: defaultName }) %>
// 这里是 mobile 的menu
<div class="navbar-mobile-right">
<% var type = 'mobile' %>
<%- partial('_partial/search', { name: type }) %>
<div class="menu-toggle" onclick="mobileBtn()">☰ 目录</div>
</div>
添加搜索框的js, 搜索代码
创建搜索代码
点击查看代码
<script>
function searchToggle() {
const width = $(document.body).width()
if(width > 479) {
return;
}
const search = $('.search');
const searchForm = $('.form-search')
if(!search.hasClass("mobile-search")) {
search.addClass("mobile-search");
} else {
search.removeClass("mobile-search");
}
}
function search(searchInputEl, formEl, flag) {
const path = "<%= config.root %>" + "<%= config.search.path %>"; // 可以在public 下查看这个search.json
$(formEl).submit(function(e){
e.preventDefault();
let target = null
if(searchInputEl == null) {
const screenWidth = $(document.body).width();
target = screenWidth > 479 ? $('#pc-search-input') : $('#mobile-search-input');
console.log(target);
} else {
target = $(searchInputEl)
}
if(!flag && target.val() === '') {
return ;
}
$("#u-search").fadeIn(500, function() {
$("body > .wrapper").addClass("modal-active");
$.ajax({
url: path,
dataType: "json",
beforeSend: function (xhr) {
$input = target.val();
$(".form-input").val($input);
const loadingBar = $('.search-loading-bar')
loadingBar.css({
width:'100%',
display: 'block'
});
},
success: function( datas ) {
// console.log(datas);
const $resultPanel = $(".modal-body")[0];
let str = `<ul class="modal-results">`;
var keywords = $(".form-input").val().trim().toLowerCase().split(/[\s\-]+/);
$resultPanel.innerHTML = "";
let hasResult = false
let text = `<div class="no-result">找不到与关键词相关的内容....</div>`;
if ($(".form-input").val().trim().length <= 0) {
// 没有结果
$resultPanel.innerHTML = text;
return;
}
datas.forEach(function (data) {
var isMatch = true;
if (!data.title || data.title.trim() === '') {
data.title = "Untitled";
}
var data_title = data.title.trim().toLowerCase();
var data_content = data.content.trim().replace(/<[^>]+>/g, "").toLowerCase();
var data_url = data.url;
var index_title = -1;
var index_content = -1;
var first_occur = -1;
// only match artiles with not empty contents
if (data_content !== '') {
keywords.forEach(function (keyword, i) {
index_title = data_title.indexOf(keyword);
index_content = data_content.indexOf(keyword);
if (index_title < 0 && index_content < 0) {
isMatch = false;
} else {
hasResult = true
if (index_content < 0) {
index_content = 0;
}
if (i == 0) {
first_occur = index_content;
}
}
});
} else {
isMatch = false;
}
// show search results
if (isMatch) {
str += `<li class='result-item'><a href='${data_url}' class='result-item-detail'> <span class="title">${data_title}</span>`;
var content = data.content.trim().replace(/<[^>]+>/g, "");
if (first_occur >= 0) {
// cut out 200 characters
var start = first_occur - 40;
var end = first_occur + 160;
if (start < 0) {
start = 0;
}
if (start == 0) {
end = 200;
}
if (end > content.length) {
end = content.length;
}
var match_content = content.substring(start, end);
// highlight all keywords
keywords.forEach(function (keyword) {
var regS = new RegExp(keyword, "gi");
match_content = match_content.replace(regS, `<em class="search-keyword">${keyword}</em>`);
});
str += `<span class="content"> ${match_content} ...</span></a>`;
}
str += "</li>";
}
});
str += "</ul>";
if(hasResult) {
$resultPanel.innerHTML = str;
} else {
$resultPanel.innerHTML = text;
}
},
complete: function() {
setTimeout(() => {
const loadingBar = $('.search-loading-bar')
loadingBar.css({
width:'0%',
display: 'none'
});
}, 300)
}
});
})
});
}
$(document).ready(function() {
$('.modal-close').click(function () {
$("#u-search").fadeOut();
$("body > .wrapper").removeClass("modal-active")
})
$('.modal-overlay').click(function() {
$("#u-search").fadeOut();
$("body > .wrapper").removeClass("modal-active")
})
search(null, ".form-search", false)
search("#u-search-modal-form .form-input", ".u-search-modal-form", true)
})
</script>
在 themes\Chic\layout\_partial\head.ejs
中添加上面的以下代码,表示启动js
<%# search %>
<% if(config.search && config.search.enable ) { %>
<%- partial('_plugins/search.ejs') %>
<% } %>
以上就是创建搜索框的全过程了,当然了我上面写的有点乱,可以自行整理一下