Bulk conversion of embedded image tiddlers into _cannonicall_uri tiddlers

<$let
    tids={{{ [all[tiddlers]!is[system]!is[shadow]search:text[.png]enlist-input[]format:titlelist[]join[ ]] }}}
	imgfile="\.(jpg|png|gif)$"
	rb="]]"
	img="[img["
	imgs={{{ [<tids>get[text]split<rb>] :map[split<img>last[]] +[regexp<imgfile>format:titlelist[]join[ ]] }}}
    img-tids={{{ [enlist<imgs>] }}}
    img-tid-title={{{ [<img-tids>split[/]last[]]   }}}
>
<$button>
<$action-sendmessage $message="tm-new-tiddler" title=<<img-tid-title>>  _canonical_uri=<<img>> label=""/>
New Tiddler
</$button>

</$let>

I have many images stored in tiddlers in [img[]] format. I am trying to convert those images in [img[]] format to separate image tiddlers with _canonical_uri field. But my code is not working. Can someone help

Intuitively it looks like you miss a loop (<$list> widget) somewhere between computing your img-tids variable and trying to split each image name in img-tid-title.

Fred

I haven’t really tested this since I don’t use [img[]] constructions in any of my wikis, but perhaps it can get you started:

<$let
	imgfile="\.(jpg|png|gif)"
	rb="]]"
	img="[img["
>
<$button>New Tiddlers
<$list filter="[all[tiddlers]!is[system]!is[shadow]search:text:regexp<imgfile>]" variable="tid">
<$list filter="[<tid>get[text]split<rb>] :map[split<img>butfirst[]] +[regexp<imgfile>!is[tiddler]]" variable="imgs">
	<$action-createtiddler
		$basetitle={{{ [<imgs>split[/]last[]] }}}
		_canonical_uri=<<imgs>>
		type=`image/${ [<imgs>split[.]last[]] }$`
		label="">
	<$action-listops $field="output" $subfilter="[<createTiddler-title>]" /> 
	</$action-createtiddler>
</$list>
</$list>
</$button>
</$let>

Some notes:

  • I don’t seen any particular benefit to using the format:titlelist[]join[ ] + enlist combination here (and also note that, in your original variable definitions, you have an unnecessary enlist-input[] in tids= and would need enlist<tids> in imgs=).
  • +[regexp<imgfile>!is[tiddler]] in the second $list means that the button will only create a new image tiddler if you don’t already have a tiddler by that title. This should prevent you from overwriting/duplicating anything.
  • I used $action-createtiddler in place of <$action-sendmessage $message="tm-new-tiddler" so the newly-created tiddlers won’t be immediately added to your story river (which seemed likely to cause problems if you have more than a few!)
  • I added the type= line to programmatically add an appropriate type field based on the image file suffix. Without the correct tiddler type, _canonical_uri won’t be handled correctly.
  • I also added the <$action-listops $field="output" $subfilter="[<createTiddler-title>]" />, which adds each newly-created title to the output field of the tiddler where you use this button.
    • This will let you use, for example, <<list-links "[enlist{!!output}]">> to get a quick list of all the image tiddlers you’ve just added.
    • If you don’t need this list, you can replace
>
	<$action-listops $field="output" $subfilter="[<createTiddler-title>]" /> 
	</$action-createtiddler>

in the above code with />

1 Like

This is working. Thank you @etardiff for the solution. Always a helping hand for us. If possible, can you suggest a way to remove those [img[]] format images and replace it with transclusion of these newly created image tiddlers?

Here’s a second button — use it after you’ve created your image tiddlers, and remember to back up your wiki first! It may be rather slow if you have a lot of images since it’s checking all your image tiddlers against all tiddlers that contain an image.

<$let
	imgfile="\.(jpg|png|gif)"
	images={{{ [all[tiddlers]!is[system]] :filter[get[type]prefix[image/]] +[format:titlelist[]join[ ]] }}}
>
<$button> Convert
<$list filter="[all[tiddlers]!is[system]!is[shadow]search:text:regexp<imgfile>]">
<$list filter="[enlist<images>]" variable="image">
<$let
	old=`[img[${ [<image>get[_canonical_uri]] }$]]`
	new=`{{$(image)$}}`
>
	<$action-setfield text={{{ [{!!text}search-replace:g<old>,<new>] }}} />
</$let>
</$list>
</$list>
</$button>
</$let>
2 Likes

Thank you @etardiff
Its working as expected.

@etardiff how else are you using images in your wikis.
Transclusion of image tiddlers with _canonical_uri fields ?

No, I don’t really use _canonical_uri tiddlers, either. I tend to agree with Springer and Scott in this recent thread:

Most of my tiddlers (and nearly all the ones where I use images) are rendered through view templates, so I generally store URLs/local filepaths in fields on the associated tiddler and use constructions like <$image source={{!!field}} /> or <$list filter="[enlist{!!field}]" variable=path><$image source=<<path>> /></$list> to display them programmatically.

1 Like

These can be done with _canonical_uri field also right ?
That is also just another field, but attached to type-image/png etc…
Are you trying to avoid type-image/png like tiddlers ? Any disadvantage of using type-image/png tiddlers ?

Yes, you can also transclude image tiddlers into an $image widget — and that’s a major advantage of this approach. If I decide to change my data structure in the future, all I have to do is change the <$image source= value in my template.

But like Scott, I’d like to keep my tiddler count (and my wiki file size) as low as possible; I’d prefer not to make a separate tiddler just to hold a single field value, since that tiddler will come with its own field set full of metadata I don’t actually need. And like Springer, I endeavor to keep all the information relevant to a single tiddler in that tiddler, so the context is always obvious. I think Charlie put it very well here: