Anup Chavan119 downloadsCreate custom HTML views for your notes based on filter rules. Transform how your notes are displayed.
A plugin for Obsidian that lets you create custom HTML views for your notes based on filter rules. Transform how your notes are displayed by defining custom templates that match specific files.
The plugin's main feature is custom views, which allow you to:
Perfect for creating card views, dashboards, or any custom presentation of your notes!
Let's create a simple view for movie notes. First, add a filter rule:
file.foldercontainsMoviesThen, create a template like this:
<div class="movie-card">
<h1>{{title}}</h1>
<p>Year: {{year}}</p>
<p>Rating: {{rating}}/10</p>
<div>{{file.content}}</div>
</div>
Now, any note in a folder containing "Movies" will be displayed using this custom template instead of the default markdown view!
Match files using powerful filter rules based on file properties or frontmatter. You can combine multiple conditions using AND, OR, or NOR logic.
Available Properties:
file.name, file.path, file.folder, file.size, file.ctime, file.mtime, file.extensiontitle, tags, status, date)tags property (automatically detected as a list)Operators:
contains, does not contain, is, is not, starts with, ends with, is empty, is not empty=, ≠, <, ≤, >, ≥, is empty, is not emptyon, not on, before, on or before, after, on or after, is empty, is not emptycontains, does not contain, is empty, is not emptyis (true/false)Write custom HTML templates using a simple placeholder syntax. Access file properties using {{file.property}} and frontmatter properties using {{property}}.
Basic Placeholders:
{{file.name}} - The full filename (e.g., "My Note.md"){{file.basename}} - The filename without extension (e.g., "My Note"){{file.path}} - The full file path{{file.folder}} - The folder path{{file.size}} - File size in bytes{{file.ctime}} - Creation timestamp{{file.mtime}} - Modification timestamp{{file.content}} - The note body rendered as markdown{{file.tags}} - File tags (from both body and frontmatter){{property}} - Any frontmatter property (e.g., {{title}}, {{cover}}, {{rating}})Array Access:
{{file.tags[0]}} - First tag{{file.tags[1]}} - Second tagTransform values using filter chains. Chain multiple filters together using the pipe (|) operator.
Example:
<h1>{{title | capitalize}}</h1>
<p>Published: {{date | date:"MMMM DD, YYYY"}}</p>
<p>Tags: {{file.tags | join:", " | wikilink}}</p>
Available Filters:
date:"FORMAT" - Format a date (e.g., date:"YYYY-MM-DD", date:"MMMM DD, YYYY")date:"FORMAT":"INPUT_FORMAT" - Parse and format a date with custom input formatdate_modify:"+1 year" - Modify a date (e.g., "+1 year", "-2 months")capitalize - Capitalize first letterupper - Convert to uppercaselower - Convert to lowercasetitle - Title casecamel - Convert to camelCasekebab - Convert to kebab-casesnake - Convert to snake_casetrim - Remove leading/trailing whitespacereplace:"search":"replace" - Replace text (supports regex: replace:"/pattern/flags":"replace")wikilink:"alias" - Convert to wikilink [[value|alias]]link:"text" - Convert to markdown link [text](value)image:"alt" - Convert to markdown image blockquote - Convert each line to blockquotesplit:"," - Split string into arrayjoin:", " - Join array into stringfirst - Get first elementlast - Get last elementslice:0:5 - Slice array or stringcount - Get length of array or stringstrip_tags - Remove HTML tagscalc:"+10" - Perform calculation (+, -, *, /, ^)The plugin works in different view modes based on your settings:
You can create multiple custom views. The plugin will use the first matching view for each file. This allows you to have different templates for different types of notes.
Example:
file.folder contains "Movies")file.folder contains "Books")file.status is "active")You can include <script> tags in your templates for dynamic behavior. Scripts are executed when the template is rendered, allowing you to add interactivity to your custom views.
<div class="interactive-card">
<h2>{{title}}</h2>
<button onclick="toggleDetails()">Show Details</button>
<div id="details" style="display: none;">{{file.content}}</div>
</div>
<script>
function toggleDetails() {
const details = document.getElementById("details");
details.style.display =
details.style.display === "none" ? "block" : "none";
}
</script>
[!WARNING] Scripts in templates are executed when the view is rendered. Be careful with scripts from untrusted sources.
Filter Rule:
file.folder contains MoviesTemplate:
<div
class="movie-card"
style="max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid var(--background-modifier-border); border-radius: 8px;"
>
<h1 style="margin-top: 0;">{{title}}</h1>
<div style="display: flex; gap: 20px; margin-bottom: 20px;">
<div><strong>Year:</strong> {{year}}</div>
<div><strong>Rating:</strong> {{rating}}/10</div>
<div><strong>Genre:</strong> {{genre | join:", "}}</div>
</div>
<div style="margin-top: 20px;">{{file.content}}</div>
</div>
Filter Rule:
file.status is activeTemplate:
<div class="project-dashboard">
<h1>{{file.name | replace:".md":"" | title}}</h1>
<div class="metadata">
<p><strong>Status:</strong> {{status | capitalize}}</p>
<p><strong>Due Date:</strong> {{due_date | date:"MMMM DD, YYYY"}}</p>
<p><strong>Progress:</strong> {{progress}}%</p>
</div>
<div class="tags">Tags: {{file.tags | join:", " | wikilink}}</div>
<hr />
<div class="content">{{file.content}}</div>
</div>
Filter Rule:
file.tags contains bookTemplate:
<div
style="display: grid; grid-template-columns: 200px 1fr; gap: 20px; padding: 20px;"
>
<div>
<img
src="https://raw.githubusercontent.com/anupchavan/obsidian-custom-views/HEAD/{{cover_image}}"
alt="{{title}}"
style="width: 100%; border-radius: 4px;"
/>
</div>
<div>
<h1>{{title}}</h1>
<p><strong>Author:</strong> {{author}}</p>
<p><strong>Published:</strong> {{published | date:"YYYY"}}</p>
<p><strong>Rating:</strong> {{rating}}/5 ⭐</p>
<div style="margin-top: 20px;">{{file.content}}</div>
</div>
</div>
The plugin adds the following commands to the Command palette:
Access settings via Settings → Custom Views.
Each view has:
For file properties:
{{file.PROPERTY[INDEX] | FILTER1:ARG1,ARG2 | FILTER2:ARG3}}
For frontmatter properties:
{{PROPERTY[INDEX] | FILTER1:ARG1,ARG2 | FILTER2:ARG3}}
PROPERTY - The property name (file property with file. prefix, or frontmatter key without prefix)[INDEX] - Optional array index (e.g., [0] for first element)| FILTER:ARGS - Optional filter chain{{file.content}} - Renders the note body as markdown. This is always rendered as markdown, regardless of context.Placeholders are rendered differently based on context:
href="{{file.path}}" or src="{{cover}}"): Returns raw string value[[links]])Filters are chained using the pipe (|) operator:
{{date | date:"YYYY-MM-DD" | upper}}
Filter arguments can be:
date:"YYYY-MM-DD"replace:"old":"new" (comma-separated, or use quotes for strings with commas)replace:"/pattern/flags":"replace"Any contributions and PRs are welcome! Feel free to open an issue or submit a pull request.