mirror of
https://github.com/olcubo/obsidian-cubox.git
synced 2026-07-22 05:43:25 +00:00
render articleView
This commit is contained in:
parent
be8ef81c63
commit
59208fb484
3 changed files with 135 additions and 47 deletions
34
src/main.ts
34
src/main.ts
|
|
@ -9,6 +9,27 @@ import { StatusSelectModal } from './modal/statusSelectModal';
|
|||
import { ALL_TAGS_ID, TagSelectModal } from './modal/tagSelectModal';
|
||||
import { ALL_STATUS_ID } from './modal/statusSelectModal';
|
||||
|
||||
|
||||
export const DEFAULT_CONTENT_TEMPLATE = `# {{{title}}}
|
||||
|
||||
{{{description}}}
|
||||
|
||||
[Read in Cubox]({{{cubox_url}}})
|
||||
[Read Original]({{{url}}})
|
||||
|
||||
{{{content}}}
|
||||
|
||||
{{#highlights.length}}
|
||||
## Annotations
|
||||
|
||||
{{#highlights}}
|
||||
> {{{text}}}
|
||||
{{{note}}}
|
||||
[Link️]({{{cubox_url}}})
|
||||
|
||||
{{/highlights}}
|
||||
{{/highlights.length}}`
|
||||
|
||||
interface CuboxSyncSettings {
|
||||
domain: string; // 可以是 'cubox.cc' | 'cubox.pro' | ''
|
||||
apiKey: string;
|
||||
|
|
@ -45,7 +66,7 @@ const DEFAULT_SETTINGS: CuboxSyncSettings = {
|
|||
targetFolder: 'Cubox',
|
||||
filenameTemplate: '{{title}}-{{create_time}}',
|
||||
frontMatterVariables: ['id', 'cubox_url', 'url', 'tags'],
|
||||
contentTemplate: '# {{{title}}}\n\n{{{description}}}\n\n[Read in Cubox]({{{cubox_url}}})\n[Read Original]({{{url}}})\n\n{{#highlights.length}}\n## Annotations\n\n{{#highlights}}\n> {{{highlight_text}}}\n{{{highlight_note}}}\n[Link️]({{{highlight_url}}})\n\n{{/highlights}}\n{{/highlights.length}}',
|
||||
contentTemplate: DEFAULT_CONTENT_TEMPLATE,
|
||||
highlightInContent: true,
|
||||
dateFormat: 'YYYY-MM-DD',
|
||||
lastSyncTime: 0,
|
||||
|
|
@ -53,6 +74,7 @@ const DEFAULT_SETTINGS: CuboxSyncSettings = {
|
|||
syncing: false
|
||||
}
|
||||
|
||||
|
||||
export default class CuboxSyncPlugin extends Plugin {
|
||||
settings: CuboxSyncSettings;
|
||||
cuboxApi: CuboxApi;
|
||||
|
|
@ -220,17 +242,17 @@ export default class CuboxSyncPlugin extends Plugin {
|
|||
fullArticle
|
||||
);
|
||||
|
||||
// const contentTemplate = this.templateProcessor.processContentTemplate(
|
||||
// this.settings.contentTemplate,
|
||||
// fullArticle
|
||||
// );
|
||||
const contentTemplate = this.templateProcessor.processContentTemplate(
|
||||
this.settings.contentTemplate,
|
||||
fullArticle
|
||||
);
|
||||
|
||||
// 组合最终内容
|
||||
let finalContent = '';
|
||||
if (frontMatter.length > 0) {
|
||||
finalContent = `---\n${frontMatter}\n---\n\n`;
|
||||
}
|
||||
finalContent += fullArticle.content;
|
||||
finalContent += contentTemplate;
|
||||
|
||||
// 创建或更新文件
|
||||
const filePath = `${this.settings.targetFolder}/${filename}.md`;
|
||||
|
|
|
|||
|
|
@ -54,12 +54,12 @@ Enter template for creating synced article content.
|
|||
<li class="highlight-item">
|
||||
{{highlight_text}}
|
||||
<ul class="highlight-sublist">
|
||||
<li>{{highlight_text}}</li>
|
||||
<li>{{highlight_url}}</li>
|
||||
<li>{{highlight_note}}</li>
|
||||
<li>{{date_highlighted}}</li>
|
||||
<li>{{highlight_id}}</li>
|
||||
<li>{{highlight_color}}</li>
|
||||
<li>{{text}}</li>
|
||||
<li>{{image_url}}</li>
|
||||
<li>{{cubox_url}}</li>
|
||||
<li>{{note}}</li>
|
||||
<li>{{color}}</li>
|
||||
<li>{{create_time}}</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>{{tags}}</li>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { CuboxArticle, CuboxHighlight } from './cuboxApi';
|
||||
import { formatDateTime, generateSafeFileArticleName } from './utils';
|
||||
//import * as Mustache from 'mustache';
|
||||
import Mustache from 'mustache';
|
||||
//import * as Mustache from 'mustache';
|
||||
import { parseYaml, stringifyYaml } from 'obsidian';
|
||||
|
||||
export const FRONT_MATTER_VARIABLES = [
|
||||
|
|
@ -21,6 +21,38 @@ export const FRONT_MATTER_VARIABLES = [
|
|||
'id'
|
||||
]
|
||||
|
||||
// Add these interfaces for the view models
|
||||
interface HighlightView {
|
||||
id: string;
|
||||
text: string;
|
||||
image_url?: string;
|
||||
cubox_url: string;
|
||||
note?: string;
|
||||
color: string;
|
||||
create_time: string;
|
||||
formatted_create_time?: string;
|
||||
}
|
||||
|
||||
interface ArticleView {
|
||||
id: string;
|
||||
title: string;
|
||||
article_title: string;
|
||||
description: string;
|
||||
url: string;
|
||||
domain: string;
|
||||
create_time: string;
|
||||
update_time: string;
|
||||
word_count: number;
|
||||
content?: string;
|
||||
cubox_url: string;
|
||||
type: string;
|
||||
formatted_create_time?: string;
|
||||
formatted_update_time?: string;
|
||||
highlights: HighlightView[];
|
||||
tags: string[];
|
||||
highlights_length: number;
|
||||
}
|
||||
|
||||
export class TemplateProcessor {
|
||||
// 存储日期格式
|
||||
private dateFormat: string = 'yyyy-MM-dd';
|
||||
|
|
@ -76,7 +108,7 @@ export class TemplateProcessor {
|
|||
}
|
||||
|
||||
/**
|
||||
* 处理前置元数据模板
|
||||
* 处理文章数据模板
|
||||
* @param templateVariables 模板字符串
|
||||
* @param article 文章数据
|
||||
*/
|
||||
|
|
@ -98,8 +130,6 @@ export class TemplateProcessor {
|
|||
article.tags &&
|
||||
article.tags.length > 0
|
||||
) {
|
||||
// tags are handled separately
|
||||
// use label names as tags
|
||||
frontMatter[variable] = article.tags
|
||||
continue
|
||||
}
|
||||
|
|
@ -137,44 +167,80 @@ export class TemplateProcessor {
|
|||
return content;
|
||||
}
|
||||
|
||||
// 准备用于 Mustache 的数据
|
||||
const data = this.prepareTemplateData(article);
|
||||
// 1. 创建 ArticleView 对象
|
||||
const articleView = this.createArticleView(article);
|
||||
|
||||
// 使用 Mustache 渲染模板
|
||||
return Mustache.render(template, data);
|
||||
// 2. 调试输出 (可以在生产环境中移除)
|
||||
console.log('ArticleView for template rendering:', JSON.stringify({
|
||||
title: articleView.title,
|
||||
highlights_length: articleView.highlights_length,
|
||||
highlights_count: articleView.highlights.length,
|
||||
first_highlight: articleView.highlights.length > 0 ? {
|
||||
text: articleView.highlights[0].text,
|
||||
note: articleView.highlights[0].note,
|
||||
cubox_url: articleView.highlights[0].cubox_url
|
||||
} : null
|
||||
}, null, 2));
|
||||
|
||||
// 3. 使用 Mustache 渲染模板
|
||||
return Mustache.render(template, articleView);
|
||||
}
|
||||
|
||||
/**
|
||||
* 准备用于 Mustache 模板的数据对象
|
||||
* @param article 文章数据
|
||||
* 创建用于模板渲染的 ArticleView 对象
|
||||
* @param article 原始文章数据
|
||||
* @returns 用于模板渲染的视图对象
|
||||
*/
|
||||
private prepareTemplateData(article: CuboxArticle): any {
|
||||
// 格式化日期
|
||||
const createDate = article.create_time || '';
|
||||
const formattedDate = createDate ? formatDateTime(createDate, this.dateFormat) : '';
|
||||
|
||||
// 格式化高亮内容
|
||||
let highlightsText = '';
|
||||
private createArticleView(article: CuboxArticle): ArticleView {
|
||||
// 创建基本的 ArticleView 对象
|
||||
const articleView: ArticleView = {
|
||||
...article,
|
||||
highlights: [],
|
||||
tags: article.tags || [],
|
||||
highlights_length: article.highlights?.length || 0,
|
||||
formatted_create_time: article.create_time ? formatDateTime(article.create_time, this.dateFormat) : '',
|
||||
formatted_update_time: article.update_time ? formatDateTime(article.update_time, this.dateFormat) : ''
|
||||
};
|
||||
|
||||
// 处理高亮内容
|
||||
if (article.highlights && article.highlights.length > 0) {
|
||||
article.highlights.forEach(highlight => {
|
||||
highlightsText += `- ${highlight.text}\n`;
|
||||
});
|
||||
articleView.highlights = article.highlights.map(highlight => this.createHighlightView(highlight));
|
||||
}
|
||||
|
||||
// 确保 Mustache 可以正确处理条件渲染
|
||||
if (articleView.highlights.length === 0) {
|
||||
articleView.highlights_length = 0;
|
||||
} else {
|
||||
articleView.highlights_length = articleView.highlights.length;
|
||||
}
|
||||
|
||||
return articleView;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建高亮视图对象
|
||||
* @param highlight 原始高亮数据
|
||||
* @returns 用于模板渲染的高亮视图对象
|
||||
*/
|
||||
private createHighlightView(highlight: CuboxHighlight): HighlightView {
|
||||
// 确保文本和注释正确处理
|
||||
const text = highlight.text || '';
|
||||
// 只有当 note 存在且不为空时才添加换行符
|
||||
const note = highlight.note && highlight.note.trim() ? highlight.note.trim() + '\n' : '';
|
||||
|
||||
// 创建高亮视图对象
|
||||
const highlightView: HighlightView = {
|
||||
...highlight,
|
||||
text: text,
|
||||
note: note,
|
||||
formatted_create_time: highlight.create_time ? formatDateTime(highlight.create_time, this.dateFormat) : ''
|
||||
};
|
||||
|
||||
// 确保所有必要的字段都存在
|
||||
if (!highlightView.cubox_url) {
|
||||
highlightView.cubox_url = '';
|
||||
}
|
||||
|
||||
// 返回包含所有可用变量的对象
|
||||
return {
|
||||
cardTitle: article.title || 'Untitled',
|
||||
createDate: formattedDate,
|
||||
content: article.content || '',
|
||||
highlights: highlightsText,
|
||||
url: article.url || '',
|
||||
domain: article.domain || '',
|
||||
// 添加原始对象,以便可以访问所有属性
|
||||
article: article,
|
||||
// 添加高亮数组,以便可以在模板中循环
|
||||
highlightsList: article.highlights || [],
|
||||
// 添加标签数组
|
||||
tags: article.tags || []
|
||||
};
|
||||
return highlightView;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue