|
|
{% extends "base.html" %}
|
|
|
|
|
|
{% block title %}{% if article %}编辑文章{% else %}新建文章{% endif %} - 个人博客{% endblock %}
|
|
|
|
|
|
{% block content %}
|
|
|
<div class="editor-container" style="
|
|
|
max-width: 1400px;
|
|
|
margin: 0 auto;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
gap: 1rem;
|
|
|
height: calc(100vh - 8rem);
|
|
|
padding: 0 1rem;
|
|
|
">
|
|
|
|
|
|
<div class="editor-header" style="
|
|
|
background: white;
|
|
|
border-radius: 8px;
|
|
|
padding: 1.25rem;
|
|
|
border: 1px solid #B3CFEF;
|
|
|
">
|
|
|
<input type="text" id="titleInput" placeholder="请输入文章标题..." value="{{ article.title if article else '' }}" style="
|
|
|
width: 100%;
|
|
|
font-size: 1.5rem;
|
|
|
border: none;
|
|
|
outline: none;
|
|
|
color: #2C3E50;
|
|
|
">
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div class="editor-toolbar" style="
|
|
|
background: white;
|
|
|
border-radius: 8px;
|
|
|
padding: 0.5rem;
|
|
|
display: flex;
|
|
|
gap: 0.25rem;
|
|
|
flex-wrap: wrap;
|
|
|
border: 1px solid #B3CFEF;
|
|
|
"></div>
|
|
|
|
|
|
|
|
|
<div class="editor-main" style="
|
|
|
display: grid;
|
|
|
grid-template-columns: 1fr 1fr;
|
|
|
gap: 1rem;
|
|
|
flex: 1;
|
|
|
min-height: 0;
|
|
|
">
|
|
|
|
|
|
<textarea id="contentInput" placeholder="开始写作..." style="
|
|
|
background: white;
|
|
|
border-radius: 8px;
|
|
|
padding: 1.25rem;
|
|
|
border: 1px solid #B3CFEF;
|
|
|
font-family: 'Monaco', 'Consolas', monospace;
|
|
|
font-size: 0.9375rem;
|
|
|
line-height: 1.6;
|
|
|
color: #2C3E50;
|
|
|
resize: none;
|
|
|
outline: none;
|
|
|
">{{ article.content if article else '' }}</textarea>
|
|
|
|
|
|
|
|
|
<div id="preview" class="markdown-preview" style="
|
|
|
background: white;
|
|
|
border-radius: 8px;
|
|
|
padding: 1.25rem;
|
|
|
border: 1px solid #B3CFEF;
|
|
|
overflow-y: auto;
|
|
|
color: #2C3E50;
|
|
|
"></div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div class="editor-footer" style="
|
|
|
background: white;
|
|
|
border-radius: 8px;
|
|
|
padding: 0.75rem 1.25rem;
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
align-items: center;
|
|
|
border: 1px solid #B3CFEF;
|
|
|
">
|
|
|
<div class="word-count" style="
|
|
|
color: #6391C5;
|
|
|
font-size: 0.875rem;
|
|
|
"></div>
|
|
|
|
|
|
<button class="save-button" style="
|
|
|
padding: 0.5rem 1rem;
|
|
|
background: #6391C5;
|
|
|
color: white;
|
|
|
border: none;
|
|
|
border-radius: 4px;
|
|
|
font-size: 0.875rem;
|
|
|
cursor: pointer;
|
|
|
transition: background-color 0.2s;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
gap: 0.5rem;
|
|
|
">
|
|
|
<i class="fas fa-save" style="font-size: 0.875rem;"></i>
|
|
|
保存文章
|
|
|
</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<input type="file" id="imageInput" style="display: none" accept="image/*">
|
|
|
|
|
|
<style>
|
|
|
|
|
|
.toolbar-button {
|
|
|
width: 32px;
|
|
|
height: 32px;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
border: 1px solid transparent;
|
|
|
border-radius: 4px;
|
|
|
color: #6391C5;
|
|
|
background: none;
|
|
|
cursor: pointer;
|
|
|
transition: all 0.2s;
|
|
|
font-size: 0.9375rem;
|
|
|
}
|
|
|
|
|
|
.toolbar-button:hover {
|
|
|
background: #f8fafc;
|
|
|
border-color: #B3CFEF;
|
|
|
}
|
|
|
|
|
|
|
|
|
.markdown-preview h1,
|
|
|
.markdown-preview h2,
|
|
|
.markdown-preview h3 {
|
|
|
margin-top: 1.5em;
|
|
|
margin-bottom: 1em;
|
|
|
color: #2C3E50;
|
|
|
}
|
|
|
|
|
|
.markdown-preview code {
|
|
|
background: #f8fafc;
|
|
|
padding: 0.2em 0.4em;
|
|
|
border-radius: 4px;
|
|
|
font-size: 0.9em;
|
|
|
color: #6391C5;
|
|
|
}
|
|
|
|
|
|
.markdown-preview pre {
|
|
|
background: #f8fafc;
|
|
|
padding: 1rem;
|
|
|
border-radius: 4px;
|
|
|
border: 1px solid #B3CFEF;
|
|
|
overflow-x: auto;
|
|
|
}
|
|
|
|
|
|
.markdown-preview pre code {
|
|
|
background: none;
|
|
|
padding: 0;
|
|
|
border-radius: 0;
|
|
|
}
|
|
|
|
|
|
.markdown-preview blockquote {
|
|
|
border-left: 4px solid #B3CFEF;
|
|
|
margin: 1em 0;
|
|
|
padding-left: 1em;
|
|
|
color: #64748b;
|
|
|
}
|
|
|
|
|
|
.markdown-preview img {
|
|
|
max-width: 100%;
|
|
|
border-radius: 4px;
|
|
|
}
|
|
|
</style>
|
|
|
|
|
|
<script>
|
|
|
|
|
|
document.getElementById('contentInput').addEventListener('focus', function() {
|
|
|
this.style.borderColor = '#6391C5';
|
|
|
});
|
|
|
|
|
|
document.getElementById('contentInput').addEventListener('blur', function() {
|
|
|
this.style.borderColor = '#B3CFEF';
|
|
|
});
|
|
|
|
|
|
|
|
|
document.getElementById('titleInput').addEventListener('focus', function() {
|
|
|
this.style.borderColor = '#6391C5';
|
|
|
});
|
|
|
|
|
|
document.getElementById('titleInput').addEventListener('blur', function() {
|
|
|
this.style.borderColor = '#B3CFEF';
|
|
|
});
|
|
|
|
|
|
|
|
|
document.querySelector('.save-button').addEventListener('mouseenter', function() {
|
|
|
this.style.background = '#5682b6';
|
|
|
});
|
|
|
|
|
|
document.querySelector('.save-button').addEventListener('mouseleave', function() {
|
|
|
this.style.background = '#6391C5';
|
|
|
});
|
|
|
</script>
|
|
|
{% endblock %}
|
|
|
|
|
|
{% block extra_js %}
|
|
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
|
|
<script src="{{ url_for('static', filename='js/editor.js') }}"></script>
|
|
|
{% endblock %} |