Skip to content

Commit

Permalink
feat: sort tag content by creation date, add setting for asc/desc (#34)
Browse files Browse the repository at this point in the history
  • Loading branch information
mjsumpter authored Feb 10, 2025
1 parent f1b02ba commit bdda265
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 12 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ To install the Obsidian Tag Page Plugin:
- **Tag Page Directory**: Customize the directory where new tag pages will be created.
- **Frontmatter Query Property**: Define the frontmatter property to store the tag query within the tag page.
- **NOTE: This property is required on all tag pages for refreshing content.**
- **Sort By Date**: Sorts content by creation date. Defaults to descending (newest content first)
- **Nested page separator**: Indicate the character used between words when created tag pages. Defaults to `_`.
- _Example_: `mytag_nested.md`
- **Include Lines**: Choose to include lines containing the tag in the tag page.
Expand Down
18 changes: 17 additions & 1 deletion main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ import {
generateTagPageContent,
swapPageContent,
} from './src/utils/pageContent';
import { PluginSettings } from './src/types';
import { PluginSettings, SortOrder } from './src/types';
import { isTagPage } from './src/utils/obsidianApi';

const DEFAULT_SETTINGS: PluginSettings = {
tagPageDir: 'Tags/',
frontmatterQueryProperty: 'tag-page-query',
sortByDate: SortOrder.DESC,
nestedSeparator: '_',
bulletedSubItems: true,
includeLines: true,
Expand Down Expand Up @@ -280,6 +281,21 @@ class TagPageSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
}),
);
new Setting(containerEl)
.setName('Sort content by Date')
.setDesc(
'Designate whether the content should be sorted in descending or ascending order. Defaults to descending (newest content first).',
)
.addDropdown((component) =>
component
.addOption(SortOrder.DESC, 'Descending')
.addOption(SortOrder.ASC, 'Ascending')
.setValue(SortOrder.DESC)
.onChange(async (value) => {
this.plugin.settings.sortByDate = value as SortOrder;
await this.plugin.saveSettings();
}),
);
new Setting(containerEl)
.setName('Nested page separator')
.setDesc(
Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "tag-page-md",
"name": "Tag Page",
"version": "1.1.0",
"version": "1.2.0",
"minAppVersion": "0.15.0",
"description": "Dynamically generate and update tag-specific pages, offering a consolidated view of each tag's references across your vault.",
"author": "Matthew Sumpter",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tag-page-md",
"version": "1.1.0",
"version": "1.2.0",
"description": "An Obsidian Extension for creating pages to capture all note content with a given tag.",
"main": "main.js",
"scripts": {
Expand Down
7 changes: 7 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
export enum SortOrder {
ASC = 'asc',
DESC = 'desc',
}

export interface PluginSettings {
tagPageDir: string;
frontmatterQueryProperty: string;
sortByDate: SortOrder;
nestedSeparator: string;
bulletedSubItems: boolean;
includeLines: boolean;
Expand All @@ -13,4 +19,5 @@ export type TagInfo = Map<string, TagMatchDetail[]>;
export interface TagMatchDetail {
stringContainingTag: string;
fileLink: string;
timestamp: number; // pulled from TFile.stat.ctime (creation time)
}
29 changes: 21 additions & 8 deletions src/utils/tagSearch.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { App, TFile, Vault } from 'obsidian';
import { PluginSettings, TagInfo } from '../types';
import { PluginSettings, SortOrder, TagInfo } from '../types';
import { isTagPage } from './obsidianApi';

/**
Expand Down Expand Up @@ -199,13 +199,13 @@ export const findBulletListsContainingTag = (
* handling cases where either, both, or none of the sources are provided.
* Each TagMatchDetail contains a string containing the tag and a file link.
*
* @param {string} fileLink - The file link to be associated with each tag match.
* @param {{fileLink: string; timestamp:number}} fileInfo - The file link to be associated with each tag match.
* @param {Map<string, string[]>?} unitsContainingTag - Optional. The map of tags to strings from findSmallestUnitsContainingTag.
* @param {Map<string, string[]>?} bulletListsContainingTag - Optional. The map of tags to bullet lists from findBulletListsContainingTag.
* @returns {TagInfo} A map of tags to arrays of TagMatchDetail objects.
*/
function consolidateTagInfo(
fileLink: string,
fileInfo: { fileLink: string; timestamp: number },
unitsContainingTag?: Map<string, string[]>,
bulletListsContainingTag?: Map<string, string[]>,
): TagInfo {
Expand All @@ -215,8 +215,8 @@ function consolidateTagInfo(
const addMatchesToConsolidatedInfo = (tag: string, matches: string[]) => {
const existingMatches = consolidatedInfo.get(tag) || [];
const newMatches = matches.map((matchString) => ({
...fileInfo,
stringContainingTag: matchString,
fileLink: fileLink,
}));
consolidatedInfo.set(tag, existingMatches.concat(newMatches));
};
Expand Down Expand Up @@ -255,10 +255,15 @@ export const processFile = async (
const fileLink = settings.fullLinkName
? `[[${file.basename}]]`
: `[[${file.basename}|*]]`;

const fileInfo = {
fileLink,
timestamp: file.stat.ctime,
};
switch (true) {
case settings.bulletedSubItems && settings.includeLines:
return consolidateTagInfo(
fileLink,
fileInfo,
findSmallestUnitsContainingTag(
fileContents,
tagOfInterest,
Expand All @@ -268,14 +273,14 @@ export const processFile = async (
);
case settings.bulletedSubItems && !settings.includeLines:
return consolidateTagInfo(
fileLink,
fileInfo,
undefined,
findBulletListsContainingTag(fileContents, tagOfInterest),
);
case !settings.bulletedSubItems && settings.includeLines:
default:
return consolidateTagInfo(
fileLink,
fileInfo,
findSmallestUnitsContainingTag(
fileContents,
tagOfInterest,
Expand Down Expand Up @@ -316,7 +321,15 @@ export const fetchTagData = async (
tagInfo.forEach((details, tag) => {
// Ensure existingDetails is never undefined by providing a default value if the key doesn't exist
const existingDetails = consolidatedTagInfo.get(tag) || [];
consolidatedTagInfo.set(tag, existingDetails.concat(details));
const combinedDetails = existingDetails.concat(details);

// Sort by timestamp
if (settings.sortByDate === SortOrder.DESC) {
combinedDetails.sort((a, b) => b.timestamp - a.timestamp);
} else {
combinedDetails.sort((a, b) => a.timestamp - b.timestamp);
}
consolidatedTagInfo.set(tag, combinedDetails);
});
});

Expand Down
3 changes: 2 additions & 1 deletion versions.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
"0.1.3": "0.15.0",
"1.0.2": "0.15.0",
"1.0.3": "0.15.0",
"1.1.0": "0.15.0"
"1.1.0": "0.15.0",
"1.2.0": "0.15.0"
}

0 comments on commit bdda265

Please sign in to comment.