diff --git a/src/main.ts b/src/main.ts
index b27db66..1e035c0 100644
--- a/src/main.ts
+++ b/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`;
diff --git a/src/templateInstructions.ts b/src/templateInstructions.ts
index 32f6be2..bfaba41 100644
--- a/src/templateInstructions.ts
+++ b/src/templateInstructions.ts
@@ -54,12 +54,12 @@ Enter template for creating synced article content.
{{highlight_text}}
- - {{highlight_text}}
- - {{highlight_url}}
- - {{highlight_note}}
- - {{date_highlighted}}
- - {{highlight_id}}
- - {{highlight_color}}
+ - {{text}}
+ - {{image_url}}
+ - {{cubox_url}}
+ - {{note}}
+ - {{color}}
+ - {{create_time}}
{{tags}}
diff --git a/src/templateProcessor.ts b/src/templateProcessor.ts
index b4fbffb..ab9ad65 100644
--- a/src/templateProcessor.ts
+++ b/src/templateProcessor.ts
@@ -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;
}
}
\ No newline at end of file