Synchronizing tags and properties

Is there a way to synchronize tags and properties? Here’s my use case:

  1. I have geo data for my project files stored as YAML under the Location property.

  2. I use the Type property to distinguish the stage my project is in (Opportunity => Estimate => Job => Archive)

  3. Both map plugins for Obsidian (Map View and Obsidian Leaflet) only use tags for filtering, not properties.

  4. To show my files as pins with different colors/icons/shapes I have to replicate data already stored as properties.

  5. I would like to synchronize a tag for the plugins to pick up with the current value of the Type property. Is there a way to do this? Perhaps with Linter? Ideally, this would be automated on file change. With the recent shift towards properties I’m surprised there isn’t some sort of tool for this kind of conversion/replication.

The MetaData Menu plugin has a way of mapping a tag to a file class – but that’s just the other way around.

This could be done with Templater which has some sort of event hook if I’m not mistaken. So it would be possible to create temporary tags for the duration of queries etc. and remove them again.
If the automatic handling of this is problematic, one could add a hotkey for creating the tags, which of course can be kept on board in YAML as well.

A (somewhat) relevant Templater snippet was talked about here.

1 Like

Just as an update for anybody trying to do this - the frontmatter generator plugin is what you’re looking for. Also useful for setting default property values.

@Jimbosis , I took a quick glance at that plugin, but I failed to understand whether it was capable of keeping your already set values for either properties being set by the plugin, or other properties you’ve already set.

In other words, will the plugin always overwrite your old properties, or can it keep your values while it stills ensures a “complete” set of properties is created?

Holroy,

It’s a bit thin on documentation. I actually FR’d the author about processing multiple conditions and he pointed out it was just basic Javascript (which I am incredibly weak on) for the template.

It allows you to selectively update properties but if that property is a list (i.e. tags) it would overwrite the entire list. You could copy the list to a variable, append a value, and then update the list but that would require some additional logic in the template. I’m not sure how else you could handle a list other than ‘if tag doesn’t exist add it’.

In my case, I don’t use tags for these files except to replicate properties so it’s a non-issue. This is the template I’m using and it sets some default values in addition to replicating some properties to tags. Everything else is left alone.

(() => {

const { type, company: initialCompany, stage: initialStage, status: initialStatus, created: initialCreated, due, reference} = file.properties || {};
const date = new Date(file.stat.ctime);
const isoString = date.toISOString().substring(0, 10);

// Initialize result with potential defaults
let result = {};

if (type === ‘Project’) {
const status = initialStatus || ‘active’;
const stage = initialStage || ‘Estimate’;
const company = initialCompany || ‘Unassigned’;
const created = initialCreated || isoString;
let reference = ${company.charAt(0)}${created.slice(2, 4)}${created.slice(5, 7)}${created.slice(8, 10)};

// Constructing the result object
result = {
  ...result,
  stage,
  status,
  company,
  created,
  due: due || created,
  reference,
  tags: [status, company, stage],
};

}

return result;
})();

Hmmm… I don’t think that’s concept is for me then, as I would like it to leave “unknown” parts of my properties as they were before, and only use a tool like this to ensure the base framework is consistent.

Holroy, what do you mean by unknown? If it encounters a property that it has no instruction for it leaves it untouched. The only destructive aspect would be with lists and you could copy the original array, transform and then write it back again.

I might have misread the documentation, which indeed is sparse, but it looked like if you had the default example of:

{
 folder: file.parent.path,
 title: file.basename,
 test: ["1", "2"]
}

And you already had something like:

---
tags: f72187
---

It would replace that with a frontmatter consisting of only the template fields. And it was this behavior related to my existing tags field I talked about when talking about “unknown” properties, aka properties not mentioned in the template.

Testing reveals that it do respect existing fields, at least in this simple example. So my frontmatter after “applying” this template became:

---
Tags: f72187
folder: ForumStuff/f72/f72187
test:
  - "1"
  - "2"
title: f72187 frontmatter generator
---

So I might look into whether I can apply this to some other use cases of mine, where I’m not feeling to use the Metadata menu plugin and its file classes.

Glad it worked out for you. I got the sense I wasn’t explaining myself very well.

Frontmatter Generator works quite nicely with Metadata Menu. I have a ‘project’ class file with status, client, and stage properties set to cycle. Clicking the cycle button triggers the FG script and updates the associated tag. I also have it generate a reference for the file based on the first letter of the Client and the Created property date in YYMMDD format (e.g. X240402) if one doesn’t already exist.

It’s a nice helper for those of us short on the programming skills required for writing a proper plugin. Last month somebody on Reddit asked if inheritable properties were possible, i.e. could you update a property in a parent page that would propagate through linked child pages? Got thinking about it and realized Dataview and FG could be set up to do exactly that:

How to make notes created inside another inheritance the properties in a automatic way of the father note ? : ObsidianMD (reddit.com)