Skip to content

replace DataView Inline Fields in the Body by References to the new Frontmatter Fields#23

Merged
Mara-Li merged 32 commits intoMara-Li:masterfrom
SpocWeb:master
Jan 19, 2026
Merged

replace DataView Inline Fields in the Body by References to the new Frontmatter Fields#23
Mara-Li merged 32 commits intoMara-Li:masterfrom
SpocWeb:master

Conversation

@SpocWeb
Copy link
Contributor

@SpocWeb SpocWeb commented Jan 3, 2026

Hi, here is a Pull Request that implements my proposal #14 .
It adds an optional new string setting replaceInlineFieldsWith that, when not empty,
will replace all DataView Inline Fields in the Body by References to the new Frontmatter Field.

This keeps the value in the Body in sync with the Frontmatter Value,
especially when the Frontmatter is updated, e.g. by the new bases-Feature.

This Feature can be disabled by clearing the Field, so we keep your original behavior.
I have tested it on a few dozen files and will continue to do so...

@Mara-Li
Copy link
Owner

Mara-Li commented Jan 4, 2026

Hello! It is an interesting feature.

Could you please add the tests ?

  1. In fixture you set the "input" and expected the wanted results.
  2. You need to write a new test in https://github.com/Mara-Li/obsidian-dataview-properties/blob/master/tests/specs/properties.e2e.ts as you need to change the configuration to enable the option.
    Something like that:
if (fileName === "body_by_ref.md") {
					await browser.executeObsidian(({ app }, pluginId) => {
						const plugin = app.plugins.getPlugin(pluginId) as DataviewProperties;
						if (plugin) {
							//update the configuration here
							plugin.saveSettings();
						}
					}, manifest.id);
				}

@SpocWeb
Copy link
Contributor Author

SpocWeb commented Jan 6, 2026

I just got the idea that only Values should be replaced after copying them to the FrontMatter, not Expressions, because DataView evaluates only Inline Expressions. Therefore I would not replace Values that start with = or =$. I would tend to hard-code these values or would you rather have a separate regular expression for that?

@SpocWeb SpocWeb requested a review from Mara-Li January 6, 2026 15:41
@Mara-Li
Copy link
Owner

Mara-Li commented Jan 6, 2026

Well, the =$ (and equivalent for JS) are Dataview settings, so you should create a separate regex with getting it from the Dataview plugin. They are already got somewhere in the code base so you can check how I do that!

@SpocWeb
Copy link
Contributor Author

SpocWeb commented Jan 6, 2026

Hi @Mara-Li , I added a unit test pair of Files named ReplaceExpressions.md, but when running it, I don't see the results.
I suspect that the test will currently fail, because I have cascaded Expressions that are updated only after the second run of your Plugin. Can you see what the problem is?

D:\obsidian-dataview-properties>bun run e2e
$ bun run build
$ tsc --noEmit --skipLibCheck
$ node esbuild.config.mjs --production
(node:45460) ExperimentalWarning: Importing JSON modules is an experimental feature and might change at any time
(Use node --trace-warnings ... to show where the warning was created)
🚀 Production build
📤 Output directory: ./dist
✅ Build successful
$ wdio run ./wdio.conf.mts
Using obsidian vault: D:_Obsidian_Standards
Using obsidian cache dir: C:\Users\heuerm\AppData\Local\Temp.obsidian-cache

Execution of 2 workers started at 2026-01-06T19:17:27.733Z

[0-1] Using obsidian vault: D:_Obsidian_Standards
[0-0] Using obsidian vault: D:_Obsidian_Standards
[0-1] Using obsidian cache dir: C:\Users\heuerm\AppData\Local\Temp.obsidian-cache
[0-0] Using obsidian cache dir: C:\Users\heuerm\AppData\Local\Temp.obsidian-cache

and then it stops...

@SpocWeb
Copy link
Contributor Author

SpocWeb commented Jan 7, 2026

I have tested it on several thousand files and it looks very good now.
To make it easier to convert big folder structures, I changed the Folder Menu Item Behavior to include all files from all subfolders.
It took 10 Minutes to process 12000 Markdown Files and Obsidian stayed responsive.
I also found a slight problem with the regular expression and fixed it. I'm about to apply it to all 70_000 Files in my Obsidian repos.

@SpocWeb
Copy link
Contributor Author

SpocWeb commented Jan 10, 2026

I found something like a bug @Mara-Li :
although I switched off "Frontmatter cleanup" (obviously, since I remove the fields and replace them by Links to the FrontMatter),
I lose nested Properties when I re-generate the Frontmatter, but not the individual Properties, only the structured Values.
It seems like when I have structures, only a single branch is retained. Here is an example:

After first Generation:

dv_has_:
  time_:
    started: -1800000
    stopped: -774000
  duration_:
    years: "1.026e+6"
  previous_:
    item: "[[Age~1~Gelasian]]"
  next_:
    item: "[[Age~3~Chibanian]]"
  name_:
    bg: Калабрий
    de: Calabrium
    fr: Calabrien
  abbreviation: q2
  text_of_:
    color: "0xFFF2BA"

becomes after second Generation:

dv_has_:
  duration_:
    years: "1.026e+6"

The original DataView Inline-Fields in the documents were like this and I use / as the Separator:

#has_/time_/started :: -1800e3 
#has_/time_/stopped ::  -774e3 

#has_/duration_/years :: `$=(((dv.current().has_time_stopped ?? new Date().year) - dv.current().has_time_started)).toExponential(3)` 

#has_/previous_/item :: [[Age~1~Gelasian]]   
#has_/next_/item :: [[Age~3~Chibanian]]   

#has_/name_/bg  :: Калабрий
#has_/name_/de  :: Calabrium
#has_/name_/fr  :: Calabrien

#has_/abbreviation :: q2

#has_/text_of_/color :: 0xFFF2BA

Maybe you can guess what is the reason for this, since you are the specialist here
(Thank you again, I especially love this feature!)

I have added a Test File named Era-4031~Eoarchean.md to demonstrate this.
This file should be unchanged when Frontmatter cleanup is switched off,
but the test should fail, although I cannot run it.

to demonstrate that the DataView to Properties
Operation does not remove data when .
@SpocWeb
Copy link
Contributor Author

SpocWeb commented Jan 10, 2026

Hi, I managed to solve the problem with the loss of nested Properties on re-processing a file
by implementing deep merging with my latest pull request.
I also added a Unit-test to demonstrate the deepMerge Method.

@Mara-Li
Copy link
Owner

Mara-Li commented Jan 10, 2026

Create a new empty vault and it should works?
Did you created the.env file?

@Mara-Li
Copy link
Owner

Mara-Li commented Jan 13, 2026

Also thanks for the bug fix!

@SpocWeb
Copy link
Contributor Author

SpocWeb commented Jan 13, 2026

OK, finally the e2e Tests work. :-)
Thank you for your patience.
One strange thing is that the previous expected Result of dv_list.md contains the "Welcome.md" which does not happen when I run it, although I left it in the newly created vault.

src/main.ts Outdated
* Returns true for primitives, dates, durations, and simple Dataview links
* Returns false for arrays, plain objects, and other complex types
*/
private isScalarValue(value: any): boolean {
Copy link
Owner

@Mara-Li Mara-Li Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unexpected any, use another type or way (maybe use unknow?)
They are probably better way to do it, probably with a library?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well this Method is targeted especially to Dataview scalar types which is not supported by libraries.
I'd rather keep it.

src/main.ts Outdated
* Normalize a value for frontmatter serialization
* Converts DateTime objects to date-only strings to avoid timezone issues
*/
private normalizeValueForFrontmatter(value: any): any {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unexpected any, specify a different type

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you propose? It could be any of Number, Luxon.Date, string, etc.

src/main.ts Outdated
/**
* Interpolate template string with actual values
*/
private formatReplacement(key: string, value: any): string {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unexpected any, specify a different type

Copy link
Contributor Author

@SpocWeb SpocWeb Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, what do you propose @Mara-Li ? the argument could be any of Number, Luxon.Date, string, etc.

Mara-Li and others added 7 commits January 15, 2026 09:11
@Mara-Li
Copy link
Owner

Mara-Li commented Jan 16, 2026

If possible could you please allow edit by maintener ? I had fixed some of the issue i found.

@Mara-Li
Copy link
Owner

Mara-Li commented Jan 18, 2026

@SpocWeb

@SpocWeb
Copy link
Contributor Author

SpocWeb commented Jan 18, 2026

If possible could you please allow edit by maintener ? I had fixed some of the issue i found.

Sure @Mara-Li , but I thought I had already done this:
image

@SpocWeb
Copy link
Contributor Author

SpocWeb commented Jan 18, 2026

Additionally I have now added you as a collaborator on my fork of this project, so you should be able to push there:
https://github.com/SpocWeb/obsidian-dataview-properties

fields & frontmatter are considered by obsidian like `Record<string, any>`
@SpocWeb
Copy link
Contributor Author

SpocWeb commented Jan 19, 2026

@Mara-Li I tested it. This is all fine with me, what next?

@Mara-Li
Copy link
Owner

Mara-Li commented Jan 19, 2026

I will merge and publish it! Probably tomorrow.

@Mara-Li Mara-Li merged commit e249971 into Mara-Li:master Jan 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants