Code to create a Tags folder and tags

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.

You can also ask ChatGPT… [How to] Post correctly formatted and colorized code on the forum? . :winking_face_with_tongue:

Oh my, that cut and paste did not go well lol

It does work for me unchanged on Windows.

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.)

Dan,

Thank you for updating the code. It works great.

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.

Thanks for your help,
Mr. Brad B. VA