Struggling With Tag Folder Name

So,

model = Sketchup.active_model.layers
model["Tag_Name"].visible? == true ? model["Tag_Name"].visible = false : model["Tag_Name"].visible = true

The above works for me, however, trying to do the same with a Tag Folder name has eluded me, but the following works…

model = Sketchup.active_model.layers.folders
model[0].visible? == true ? model[0].visible = false : model[0].visible = true

In the above, if I use…

["Tag_Folder_Name"]

I get an error

Your combining of model as a reference to the model.layers and then the model.layers.folders is confusing.
Why not let model be the model
then model.layers be the layers
and layers.folders be the list of folders ?

Then you can iterate the layer folders to get their names etc…
You can’t pass a string [name] directly to the folders collection to find an entry, only integer refs work…
e.g.

folder = nil
folders.each{|f| folder = f if f.name == 'Tag_Folder_Name' }

Now you have a reference to the folder named ‘Tag_Folder_Name’… if it exists…

Thanks TIG

This is because the getter methods return “plain-Jane” Ruby arrays and not collection class instances (like model#layers does.) So the #[] method takes either an index or a range (if you want more than 1 member returned as a subarray.)

FYI, this does a similar job …

folder = folders.find {|f| f.name == 'Tag_Folder_Name' }

There is a caveat with tag folders, and that is that duplicate names are allowed (by design) to occur.

Using Enumerable#find, if the folder with the name is not found, then folder will be nil.
But if a match is found, the iterator stops on the first match and returns it.

In TIG’s above example, the #each iterator will not stop on the first match but continues to iterate through the entire array, and the resultant folder can be the last match instead of the first.

You can check for duplicates via:

found = folders.find_all {|f| f.name == 'Tag_Folder_Name' }

The result will always be an array (either empty or with 1 or more matches.)

1 Like