I’m trying my hand at learning Ruby in order to develop some tools. My first attempt is to create a new Tags Folder and putting a series of Tags within the folder. It is not currently working. Here is the code: (I know there is probably a way to have this show as code but I don’t know how yet.)
require 'sketchup.rb'
module LayerFolderCreator
extend self
# List of the child layers.
Layers_List = [
'Dimensions',
'Fixtures',
'Floor',
'Structures',
'Misc',
'Walls-Ext',
'Walls-Int'
]
def createFolderAndLayers
# Prompt the user for the layer folder name and a number prefix.
prompts = ["Tag Folder Name:", "Number Prefix:"]
defaults = ["My Folder", "1"]
input = UI.inputbox(prompts, defaults, "Create Tag Folder and Tags")
return unless input # User hit Cancel
# Get input results
folder_name = input[0].strip
number_prefix = input[1].strip
# Create folder
manager = Sketchup.active_model.layers
folder = manager.add_folder(folder_name)
# Create tags and add them to the folder
Layers_List.each do |child_layer_name|
layer_full_name = "#{number_prefix}.#{child_layer_name}"
layer = manager.add_layer(layer_full_name)
folder.add_layer(layer)
end
end
# Add to Extensions menu
unless file_loaded?(__FILE__)
menu = UI.menu("Plugins") || UI.menu("Extensions")
menu.add_item("Create Tag Folder and Tags") {
createFolderAndLayers
}
file_loaded(__FILE__)
end
end
I setup a template folder with all of my folders and tags. That seems to be an easier approach than trying to run ruby each time you start a new project, right? But I have found ChatGPT does pretty good with Ruby. Claude Sonnet also does pretty well.
All your extension submodules should be within a unique top level namespace module.
Here is a slightly modified edition that checks if the tag folder name is already in use:
# encoding: UTF-8
module BradBumgarner
module LayerFolderCreator
extend self
# List of the child layers.
Layers_List ||= [
'Dimensions',
'Fixtures',
'Floor',
'Structures',
'Misc',
'Walls-Ext',
'Walls-Int'
]
def create_folder_and_layers
# Prompt the user for the layer folder name and a number prefix.
prompts = ["Tag Folder Name:", "Number Prefix:"]
defaults = ["My Folder", "1"]
input = UI.inputbox(prompts, defaults, "Create Tag Folder and Tags")
return unless input # User hit Cancel
# Get input results
folder_name = input[0].strip
number_prefix = input[1].strip
if folder_name.empty?
UI.messagebox('Tag Folder Name cannot be empty!')
return
end
if number_prefix.empty?
UI.messagebox('Number Prefix cannot be empty!')
return
end
# Get the layers manager
manager = Sketchup.active_model.layers
folder = nil
# Check for existing folder
found = manager.folders.find { |f| f.name == folder_name }
if found
choice = UI.messagebox('Tag Folder Name already exists! Continue?', MB_YESNO)
if choice == IDYES
choice = UI.messagebox('Use existing Tag Folder?', MB_YESNO)
if choice == IDYES
folder = found
else
choice = UI.messagebox('Rename existing Tag Folder?', MB_YESNO)
if choice == IDYES
input = UI.inputbox(['New Folder Name:'], [found.name], "Rename Tag Folder")
found.name= input[0] if input && input[0] != found.name
end
# Create new folder
folder = manager.add_folder(folder_name)
end
else
return
end
else
# Create new folder
folder = manager.add_folder(folder_name)
end
unless folder
msg = 'Error creating / getting tag folder: "%s"' % folder_name
puts msg
UI.messagebox(msg)
end
num = 0
# Create tags and add them to the folder
Layers_List.each do |child_layer_name|
layer_full_name = "#{number_prefix}.#{child_layer_name}"
unless manager[layer_full_name] # layer already exists
layer = manager.add_layer(layer_full_name)
num += 1 if layer
folder.add_layer(layer)
end
end
UI.messagebox('%d new layers created in tag folder "%s".' % [num,folder_name])
end ### create_folder_and_layers()
# Add to Extensions menu
unless defined?(@loaded)
menu = UI.menu("Plugins") || UI.menu("Extensions")
menu.add_item("Create Tag Folder and Tags") {
create_folder_and_layers()
}
@loaded = true
end
end # extension submodule
end # toplevel namespace module
Notice that I renamed the method from createFolderAndLayers to create_folder_and_layers. This is Ruby convention. Class and module identifiers are SnakeCase not method names.
Also, the require "sketchup" is not needed (as it is loaded before any extensions begin to load.) In addition, never specify a filetype with either require or Sketchup.require method calls. (Doing so will eventually “bite you in the butt”.) Only the global load() needs a full path, filename including filetype. (We don’t normally use it unless reloading a Ruby file during development.)
I’m just getting started working with Ruby. Years ago I was pretty decent working with various scripting languages. Unfortunately I don’t think I retained a lot of that. LOL I did have help from AI to start the code I submitted. Looks like I need to look into learning Ruby the proper way.