@@ -5,6 +5,14 @@ import { escapeBody } from "./util/escapeUtils";
55import { extractProperties , updateProperties } from "./util/properties" ;
66import { NoticeManager } from "./notice-manager" ;
77import { GitHubClient } from "./github-client" ;
8+ import {
9+ processTemplate ,
10+ createIssueTemplateData ,
11+ createPullRequestTemplateData ,
12+ processFilenameTemplate ,
13+ processContentTemplate ,
14+ extractNumberFromFilename
15+ } from "./util/templateUtils" ;
816
917export class FileManager {
1018 constructor (
@@ -14,6 +22,25 @@ export class FileManager {
1422 private gitHubClient : GitHubClient ,
1523 ) { }
1624
25+ /**
26+ * Load template content from a file
27+ */
28+ private async loadTemplateContent ( templatePath : string ) : Promise < string | null > {
29+ if ( ! templatePath || templatePath . trim ( ) === "" ) {
30+ return null ;
31+ }
32+
33+ try {
34+ const templateFile = this . app . vault . getAbstractFileByPath ( templatePath . trim ( ) ) ;
35+ if ( templateFile instanceof TFile ) {
36+ return await this . app . vault . read ( templateFile ) ;
37+ }
38+ } catch ( error ) {
39+ this . noticeManager . warning ( `Could not load template file: ${ templatePath } ` ) ;
40+ }
41+ return null ;
42+ }
43+
1744 /**
1845 * Create issue files for a repository
1946 */
@@ -234,9 +261,15 @@ export class FileManager {
234261 ) ;
235262
236263 for ( const file of files ) {
237- const fileNumberString = file . name
238- . replace ( ".md" , "" )
239- . replace ( "Issue - " , "" ) ;
264+ const fileNumberString = extractNumberFromFilename (
265+ file . name ,
266+ repo . issueNoteTemplate || "Issue - {number}"
267+ ) ;
268+
269+ if ( ! fileNumberString ) {
270+ // If we can't extract a number, skip this file
271+ continue ;
272+ }
240273
241274 const correspondingIssue =
242275 allIssuesIncludingRecentlyClosed . find (
@@ -292,9 +325,16 @@ export class FileManager {
292325 ) ;
293326
294327 for ( const file of files ) {
295- const fileNumberString = file . name
296- . replace ( ".md" , "" )
297- . replace ( "Pull Request - " , "" ) ;
328+ const fileNumberString = extractNumberFromFilename (
329+ file . name ,
330+ repo . pullRequestNoteTemplate || "Pull Request - {number}"
331+ ) ;
332+
333+ if ( ! fileNumberString ) {
334+ // If we can't extract a number, skip this file
335+ continue ;
336+ }
337+
298338 const correspondingPR =
299339 allPullRequestsIncludingRecentlyClosed . find (
300340 ( pr : any ) => pr . number . toString ( ) === fileNumberString ,
@@ -336,7 +376,14 @@ export class FileManager {
336376 repoCleaned : string ,
337377 issue : any ,
338378 ) : Promise < void > {
339- const fileName = `Issue - ${ issue . number } .md` ;
379+ // Generate filename using template
380+ const templateData = createIssueTemplateData ( issue , repo . repository ) ;
381+ const baseFileName = processFilenameTemplate (
382+ repo . issueNoteTemplate || "Issue - {number}" ,
383+ templateData ,
384+ this . settings . dateFormat
385+ ) ;
386+ const fileName = `${ baseFileName } .md` ;
340387 const issueFolderPath = this . getIssueFolderPath ( repo , ownerCleaned , repoCleaned ) ;
341388
342389 // Ensure folder structure exists
@@ -368,27 +415,16 @@ export class FileManager {
368415 ) ;
369416 }
370417
371- let content = this . createIssueContent ( issue , repo , comments ) ;
418+ let content = await this . createIssueContent ( issue , repo , comments ) ;
372419
373420 if ( file ) {
374421 if ( file instanceof TFile ) {
375- // Use Obsidian's MetadataCache to get frontmatter
376- const properties = extractProperties ( this . app , file ) ;
377- const updateModeText = properties . updateMode ;
378-
379- if ( ! updateModeText ) {
380- this . noticeManager . warning (
381- `No valid update mode found for issue ${ issue . number } . Using repository setting.` ,
382- ) ;
383- }
384-
385- const updateMode = updateModeText
386- ? updateModeText . toLowerCase ( ) . replace ( '"' , "" )
387- : repo . issueUpdateMode ;
422+ // Use current repository updateMode setting (not the old value from file properties)
423+ const updateMode = repo . issueUpdateMode ;
388424
389425 if ( updateMode === "update" ) {
390426 // Create the complete new content with updated frontmatter
391- const updatedContent = this . createIssueContent (
427+ const updatedContent = await this . createIssueContent (
392428 issue ,
393429 repo ,
394430 comments ,
@@ -437,7 +473,14 @@ export class FileManager {
437473 repoCleaned : string ,
438474 pr : any ,
439475 ) : Promise < void > {
440- const fileName = `Pull Request - ${ pr . number } .md` ;
476+ // Generate filename using template
477+ const templateData = createPullRequestTemplateData ( pr , repo . repository ) ;
478+ const baseFileName = processFilenameTemplate (
479+ repo . pullRequestNoteTemplate || "PR - {number}" ,
480+ templateData ,
481+ this . settings . dateFormat
482+ ) ;
483+ const fileName = `${ baseFileName } .md` ;
441484 const pullRequestFolderPath = this . getPullRequestFolderPath ( repo , ownerCleaned , repoCleaned ) ;
442485
443486 // Ensure folder structure exists
@@ -469,27 +512,16 @@ export class FileManager {
469512 ) ;
470513 }
471514
472- let content = this . createPullRequestContent ( pr , repo , comments ) ;
515+ let content = await this . createPullRequestContent ( pr , repo , comments ) ;
473516
474517 if ( file ) {
475518 if ( file instanceof TFile ) {
476- // Use Obsidian's MetadataCache to get frontmatter
477- const properties = extractProperties ( this . app , file ) ;
478- const updateModeText = properties . updateMode ;
479-
480- if ( ! updateModeText ) {
481- this . noticeManager . warning (
482- `No valid update mode found for PR ${ pr . number } . Using repository setting.` ,
483- ) ;
484- }
485-
486- const updateMode = updateModeText
487- ? updateModeText . toLowerCase ( ) . replace ( '"' , "" )
488- : repo . pullRequestUpdateMode ;
519+ // Use current repository updateMode setting (not the old value from file properties)
520+ const updateMode = repo . pullRequestUpdateMode ;
489521
490522 if ( updateMode === "update" ) {
491523 // Create the complete new content with updated frontmatter
492- const updatedContent = this . createPullRequestContent (
524+ const updatedContent = await this . createPullRequestContent (
493525 pr ,
494526 repo ,
495527 comments ,
@@ -540,11 +572,27 @@ export class FileManager {
540572 }
541573 }
542574
543- private createIssueContent (
575+ private async createIssueContent (
544576 issue : any ,
545577 repo : RepositoryTracking ,
546578 comments : any [ ] ,
547- ) : string {
579+ ) : Promise < string > {
580+ // Check if custom template is enabled and load template content
581+ if ( repo . useCustomIssueContentTemplate && repo . issueContentTemplate ) {
582+ const templateContent = await this . loadTemplateContent ( repo . issueContentTemplate ) ;
583+ if ( templateContent ) {
584+ const templateData = createIssueTemplateData (
585+ issue ,
586+ repo . repository ,
587+ comments ,
588+ this . settings . dateFormat ,
589+ this . settings . escapeMode
590+ ) ;
591+ return processContentTemplate ( templateContent , templateData , this . settings . dateFormat ) ;
592+ }
593+ }
594+
595+ // Fallback to default template
548596 return `---
549597title: "${ escapeBody ( issue . title , this . settings . escapeMode ) } "
550598status: "${ issue . state } "
@@ -580,11 +628,27 @@ ${this.formatComments(comments, this.settings.escapeMode)}
580628` ;
581629 }
582630
583- private createPullRequestContent (
631+ private async createPullRequestContent (
584632 pr : any ,
585633 repo : RepositoryTracking ,
586634 comments : any [ ] ,
587- ) : string {
635+ ) : Promise < string > {
636+ // Check if custom template is enabled and load template content
637+ if ( repo . useCustomPullRequestContentTemplate && repo . pullRequestContentTemplate ) {
638+ const templateContent = await this . loadTemplateContent ( repo . pullRequestContentTemplate ) ;
639+ if ( templateContent ) {
640+ const templateData = createPullRequestTemplateData (
641+ pr ,
642+ repo . repository ,
643+ comments ,
644+ this . settings . dateFormat ,
645+ this . settings . escapeMode
646+ ) ;
647+ return processContentTemplate ( templateContent , templateData , this . settings . dateFormat ) ;
648+ }
649+ }
650+
651+ // Fallback to default template
588652 return `---
589653title: "${ escapeBody ( pr . title , this . settings . escapeMode ) } "
590654status: "${ pr . state } "
0 commit comments