# Suggestion: foreach loop in websource scripts

**URL:** https://community.mp3tag.de/t/suggestion-foreach-loop-in-websource-scripts/70539
**Category:** Web Sources Discussion
**Created:** [January 21, 2026, 1:25pm UTC](https://community.mp3tag.de/t/suggestion-foreach-loop-in-websource-scripts/70539 "2026-01-21T13:25:42Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![yorickausyps](https://community.mp3tag.de/letter_avatar_proxy/v4/letter/y/f6c823/32.png) [@yorickausyps](https://community.mp3tag.de/u/yorickausyps)
#### Post date: [January 21, 2026, 1:25pm UTC](https://community.mp3tag.de/t/suggestion-foreach-loop-in-websource-scripts/70539/1 "2026-01-21T13:25:42Z")

</div>

Recent extensions to websource scripts like the %placeholder% syntax made it possible, to write code that use output buffers like "real" variables. Beside the reuse of their values in other strings

- they can be logical variables, where empty means false and having any content means true, and that are used with the commands `ifoutput` and `ifnotoutput`.
- they can be pointer variables, when holding the name of another output buffer in %placeholder%, with `sayoutput`, `set`, `outputto`, `ifoutput` and `ifnotoutput`commands.
- they can build an (associative) array, by using a name with fixed and variable parts, e.g. `"Array_%Index%"`.

This means that we can write code, that abstracts from actual values and can be used in the body of a loop. Sadly to say but in my opinion there currently is no appropriate looping command available.  
The `do...while` command is not really useable, because it can't be nested, occupies the input buffer and is very complicated to get it right. The `json_foreach` command can't be used, because we don't have a JSON object here (and if we are already in json mode we can't switch back and forth between different json objects). But `json_foreach` is a good example of what would be useful here.  
The suggested `foreach` command looks like this:

```auto
foreach "index" "value-list" "separator"
 # body
foreach_end

```

The first parameter `"index"` iterates through the strings in second parameter `"value-list"`, separated by the third.  
It should be allowed to nest `foreach` loops und the input buffer should not be changed by the loop.

The following example shows what actual is possible. (It builds a combination of three filter components for a regular exression.)

```auto
# Definiton of an array
set "Filter_Composer" "Written[-]By|Composed By|Music By|Songwriter"
set "Filter_Lyricist" "Lyrics By|Words By"
set "Filter_Arranger" "Arranged By|Adapted By"
# Building a filter consisting of above components
set "Join"
set "Filter_Any_Role"
outputto "Filter_Any_Role"

# Unrolled loop
set "Temp_Name" "Composer"
ifoutput "Filter_%Temp_Name%"
	sayoutput "Join"
	sayoutput "Filter_%Temp_Name%"
	set "Join" "|"
endif
set "Temp_Name" "Lyricist"
ifoutput "Filter_%Temp_Name%"
	sayoutput "Join"
	sayoutput "Filter_%Temp_Name%"
	set "Join" "|"
endif
set "Temp_Name" "Arranger"
ifoutput "Filter_%Temp_Name%"
	sayoutput "Join"
	sayoutput "Filter_%Temp_Name%"
	set "Join" "|"
endif

```

And that's how a `foreach` command could improve the above unrolled loop:

```auto
foreach "Temp_Name" "Composer,Lyricist,Arranger" ","
	ifoutput "Filter_%Temp_Name%"
		sayoutput "Join"
		sayoutput "Filter_%Temp_Name%"
		set "Join" "|"
	endif
foreach_end 

```

I currently have to copy and paste over 100 lines of code for every tag field I want to support in my discogs websource script. With the proposed `foreach` loop available the script could be up to one third shorter and faster, and it could be more flexible be adapted to specific needs.

---

<div class="post-metadata">

### Author: ![yorickausyps](https://community.mp3tag.de/letter_avatar_proxy/v4/letter/y/f6c823/32.png) [@yorickausyps](https://community.mp3tag.de/u/yorickausyps)
#### Post date: [January 24, 2026, 11:21am UTC](https://community.mp3tag.de/t/suggestion-foreach-loop-in-websource-scripts/70539/2 "2026-01-24T11:21:15Z")

</div>

The `foreach` command would of course be equally useful for me, if the first parameter "index" is left out and the values are emitted instead on the current input. This form could even be more useful for other cases, where operations with the string have to be carried out. Important for me is only that `foreach` can be nested and doesn't block the input buffer like the `do..while` command does for correct working. My example code would read then

```auto
foreach "Composer,Lyricist,Arranger" ","
	set "Temp_Name"
	outputto "Temp_Name"
	sayrest
	outputto "Filter_Any_Role"
	ifoutput "Filter_%Temp_Name%"
		sayoutput "Join"
		sayoutput "Filter_%Temp_Name%"
		set "Join" "|"
	endif
foreach_end 

```

What do you think about this feature?

---

<div class="post-metadata">

### Author: ![arb](https://community.mp3tag.de/letter_avatar_proxy/v4/letter/a/41988e/32.png) [@arb](https://community.mp3tag.de/u/arb)
#### Post date: [January 24, 2026, 6:29pm UTC](https://community.mp3tag.de/t/suggestion-foreach-loop-in-websource-scripts/70539/3 "2026-01-24T18:29:15Z")

</div>

I’m a bit divided: your first implementation looks interesting as a way of a command creating a dynamic variable (“index” or %index%) that goes through a set list of desired values which IS currently possible with `json_foreach` despite needing more setup with an array converted to JSON before-hand. Would this variable persist after the command or only be available during that loop?

It actually does solve part of a problem that `json_foreach` greatly suffers of not being able to output a loop’s currently selected item from the “value-list” as it’s accessible from that “index” variable. We’re still not able to output singular values from an array fed into `json_select_array` without reliance on an invariable index position or without formatting values as “key:value” for a `json_foreach` to fetch via `json_select key` or creating temporary buffers that saves/removes each value as they are used up through a loop.

Your second implementation is simpler yet more flexible as an alternative way of making a fixed loop just by removing the requirement of JSON which could be handy for HTML-based sources. More flexible because it doesn’t require setting up a variable that may/may not be required. Maybe too simple, though…?

The biggest factor is how `json_foreach` does block off access to other parts of the response that aren’t currently inside the loop. It is possible to circumvent if these JSON objects are isolated into temporary buffers to be called on when needed with `Use `→ `json “on” “current”` but it does get messy with regex. Using your proposals would allow calling whatever, wherever, whenever.

I do love new variations and combinations of existing commands that allow broader levels of control, especially JSON-less versions that can then have more purpose. I’m just unsure if a JSON-less version of this command is completely necessary when existing commands could instead be given more functionality to eradicate or at least circumvent their flaws. It might still be easier development-wise to make a clone of an existing command to be fair.

Also, would it be possible to use `SayRegexp` in your script as a solution? It could help you filter all the desired values in one go from your response per filter, just again using a `json_foreach` and temp buffers to scroll through each filter value. I used this in my TMDB#Results.inc script for getting all the cast, directors etc. from the credits.

(`Do … While` can be a right pain.)

---

<div class="post-metadata">

### Author: ![yorickausyps](https://community.mp3tag.de/letter_avatar_proxy/v4/letter/y/f6c823/32.png) [@yorickausyps](https://community.mp3tag.de/u/yorickausyps)
#### Post date: [January 25, 2026, 10:18am UTC](https://community.mp3tag.de/t/suggestion-foreach-loop-in-websource-scripts/70539/4 "2026-01-25T10:18:43Z")

</div>

Thank you @arb for your comments.

> [@arb](#):
>
> a command creating a dynamic variable

Because this would be the first command with this side effect, I think it has no chance to be implemented in this form by the developer @Florian and therefore I will prefer the second, simpler and also more "traditional" way of emitting the next value from the list of values on the current input.

> [@arb](#):
>
> that goes through a set list of desired values which IS currently possible with `json_foreach` despite needing more setup with an array converted to JSON before-hand.

I plan to use the proposed foreach command inside of up to two outer json\_foreach loops, so I doubt that it is possible to switch with `json "on" "current"` to a self constructed json object without disturbing the outer json loops.  
The structure of my script with unrolled loop currently look like this

```auto
	json_foreach "tracklist"
		json_foreach "extraartists"
			set "Index" "Composer"
			.... block with many lines
			set "Index" "Lyricist"
			.... same block as above
			set "Index" "Arranger"
			.... same block as above
		json_foreach_end
	json_foreach_end

```

And with the new `foreach` loop it would look as follows

```auto
	json_foreach "tracklist"
		json_foreach "extraartists"
			foreach "Composer,Lyricist,Arranger" ","
			.... block with many lines
			foreach_end
		json_foreach_end
	json_foreach_end

```

> [@arb](#):
>
> Also, would it be possible to use `SayRegexp` in your script as a solution?

This is only an example of what can be done with the %placeholder% syntax and it is no real problem I'm working on. It should show how to write script parts that can be used inside loops.

---

<div class="post-metadata">

### Author: ![yorickausyps](https://community.mp3tag.de/letter_avatar_proxy/v4/letter/y/f6c823/32.png) [@yorickausyps](https://community.mp3tag.de/u/yorickausyps)
#### Post date: [January 28, 2026, 11:32am UTC](https://community.mp3tag.de/t/suggestion-foreach-loop-in-websource-scripts/70539/5 "2026-01-28T11:32:34Z")

</div>

Thanks to @arb comments, I'm now using a workaround for the suggested foreach command. This workaround converts the list of strings into an json array, switches with `json "on" "current"` to this json object and then it loops with json\_foreach through the list of strings. This works at the innermost level of enclosing json\_foreach loops without flaws, and until all outer loops are finished at the json root level.  
To restart json now on the original input from the web source a backup of this data has to be made at the begin of the script. With this backup the json processing can be resumed and continued at the json root level. This illustrates the following example code with a named json array:

```auto
# a backup of input is necessary
outputto "Backup_of_Input"
sayrest
json "on" "current"

json_foreach "outer_array"

	# use a new selfmade json array to control a json_foreach loop
	set "json_object" "{"array":[{"key":"value one"},{"key":"second value"},{"key":"and so on"}]}"
	use "%json_object%"
	json "on" "current"
	json_foreach "array"
		json_select "key"
	json_foreach_end

json_foreach_end

# down at the root level return back to the original input
use "%Backup_of_Input%"
json "on" "current"

json_foreach "another_array"
json_foreach_end

```

For my project this workaround fits very well, but if someone else has the need for a json-less foreach loop, which is not located at the innermost nesting level of surrounding json\_foreach loops, it probably cannot be used.  
The suggested json-less loop `foreach ... foreach_end` inherits a further problem, because it should not overlap with loops `json_foreach ... json_foreach_end`. To solve this conflict, the commands `json_foreach_end` and `foreach_end` could be thought of being equal and both end the other foreach commands also. Alternatively the new command could be named `json_foreach_fake` and then use `json_foreach_end` to stop the iteration. 😉

---

<div class="post-metadata">

### Author: ![system](https://community.mp3tag.de/uploads/default/original/2X/c/ce7035d426cb755a7916793326d23b465222a407.png) [@system](https://community.mp3tag.de/u/system)
#### Post date: [February 27, 2026, 11:32am UTC](https://community.mp3tag.de/t/suggestion-foreach-loop-in-websource-scripts/70539/6 "2026-02-27T11:32:45Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
