How to get in Ruby the list of templates

Hi all,

For a small plugin I need a list of existing templates. But after a few hours googling or duckduck going, I still havent found any thing.

I saw a template plugin for peeking, but its not available for download. Link is broken.

Any pointers to get the templaate list.?
Thank you

This is probably not what you’re looking for, but you can get a list of the template files like this:

require 'sketchup.rb'
module Jimhami42
  module TestFile
    class << self
      def start_test()
        list = Dir.entries("C:/Program Files/SketchUp/SketchUp 2017/Resources/en-US/Templates").select {|f| !File.directory? f}
        list.each do |template|
          puts template
        end
      end
    end
    unless file_loaded?("jimhami42_test_file.rb")
      menu = UI.menu("PlugIns").add_item("Test file") { start_test() }
    file_loaded("jimhami42_test_file.rb")
    end
  end
end

The Ruby Console shows this for my computer / version:

Temp01a - Simple.skp
Temp01b - Simple.skp
Temp02a - Arch.skp
Temp02b - Arch.skp
Temp02d - Arch.skp
Temp03a - AEC.skp
Temp03b - AEC.skp
Temp03c - AEC.skp
Temp04a - Urban.skp
Temp04b - Urban.skp
Temp05a - Landscape.skp
Temp05b - Landscape.skp
Temp06a - Woodworking.skp
Temp06b - Woodworking.skp
Temp07a - Interiors.skp
Temp07b - Interiors.skp
Temp08a - 3D Printing.skp
Temp08b - 3D Printing.skp

These are each *.skp files and can be opened / imported like any other SketchUp model.

jimhami42_test_file.rbz (427 Bytes)

1 Like

A variety of shorter examples …

# Get them ...
tdir = Sketchup.get_resource_path("Templates")
file_list = Dir.chdir(tdir) { Dir["*.skp"] }

# List them ...
UI.messagebox(file_list.join("\n"), MB_MULTILINE, "Templates")

# Current one ( full path )...
previous = File.basename(Sketchup.template)

# Pick one ...
result = UI.inputbox(
  ['Choose template file '],
  [ File.basename(previous) ],
  [file_list.join('|')],
  'Pick one ...'
)
chosen =( result ? result.first : nil )

# Set template ...
Sketchup.template= File.join( tdir, chosen ) if chosen
# ... uses chosen template unless user cancelled pick:
Sketchup.file_new

# Restore previous template ...
Sketchup.template= previous
2 Likes

Good morning and thank you both.
Both scripts are usable for me, a little bit of this and a little bit of that.

However, I forgot two things to mention…

This

tdir = Sketchup.get_resource_path(“Templates”)
/Applications/SketchUp 2018/SketchUp.app/Contents/Resources/Content/Resources/en-US/Templates
(So yep, (1) I use a Mac. ;))

gives me the templates inside the app. Only the SU default one’s, ( 2 ) but it gives me not the user defined templates, meaning the template at the path what is set in the SU preferences.

This

   > list = Dir.entries("/Users/dev/Library/Application Support/SketchUp 2018/SketchUp/Templates")
    [".", "..", "Kavel.skp", "PP50 - Constructie Documentatie - Millimeters.skp"]

gives me the self created template’s. However I have to set manually the right path.

To be boldy :wink:
The main problem is, how can I read the paths set in the user preferences?
or, how to use get_resource_path to get the user defined template path

B.t.w How do you know what to use as the filename? I did search for this for hours.

Sketchup.get_resource_path(“Templates”)
.get_resource_path(filename) ⇒ String

Looking at the Menu Object I cant find a way to insert a menu item f.e just under ‘File’>‘New’
menu = UI.menu(“File”).add_item(“New…”) { chooseFromTmpl() }

Is that even possible, create a menu item where I want?

As well as the shipped Templates in the Resources folder - which the preceding examples reveal to you, as you have found you can also have another set of your own custom Templates, stored in your user’s folder-tree.
You can find this by using:

tdir2 = Sketchup.find_support_file("Templates")

It returns [on PC[
C:/Users/USERNAME/AppData/Roaming/SketchUp/SketchUp 2018/SketchUp/Templates
On a MAC there will be a similar path returned…

3 Likes

Aw, snap! Here’s we we must admit we’re geeks who’ve been at this SketchUp stuff 10 years or better.

So we know what the resource and support folder names are.

Resource

  • Templates

Support

  • Classifications
  • Components
  • Gems / Gems64 (depending upon bitness)
  • Materials
  • Plugins
  • Styles
2 Likes

@TIG - Works like a charm.

@DanRathbun - Aha, But no where documented?
Also, some times is the documentation confusing. I was also hours searching for scene’s, but they are called pages.

@All - thank you

Is that even possible, create a menu item where I want? F.e right under the File>New menu item?

Well, historically on MS Windows, the support and resources folders were beneath the binary (program/app) folders.
This was not where either platform (OSX & MS Windows) intended for application or user data to be located.

But mostly on Windows platform there was a long standing issue with Unicode string pathnames not being supported by Ruby version in the 1.8 trunk, which was SketchUp version up through v2013. (OSX had always natively supported Unicode strings and paths.)

So, in 2013 and earlier, on Windows, all the folders were in the program folder paths.
On Mac, up through v8, the "Plugins" were in "Macintosh HD/Library/Application Support/SketchUp".
For v2013, the "Plugins" folder moved to: "~/Library/Application Support/SketchUp 2013/SketchUp".
(These facts come from the Release Notes Page.)

Unicode pathname support for Windows was finally solved with the release of SketchUp 2014 which upgraded it’s embedded Ruby version to 2.0.0-p247 and also included the Ruby Standard Library for the first time.

Also with this 2014 version, the Trimble development team began migrating user data folders out of the program (binary) path into AppData paths where they belonged. (There were permissions issues with installing plugins and files in general into the program files paths with Windows Vista and later for security reasons.)

So the first year of Ruby 2, SketchUp 2014 implemented "Plugins", "Gems" and "Classifications" in the user AppData path.

The second year, SketchUp 2015 implemented a 64-bit edition for Windows, and that one had a "Gems64" folder. Otherwise they were the same 3 folders for the 32-bit edition.

The third year of Ruby 2.0, SketchUp 2016 remained the same as the previous year.

The 4th year, Ruby was updated to 2.2.4, and SketchUp 2017 no longer had a 32-bit WIndows build, so the gems folders are all named "Gem64".
On Windows, they moved the default content that comes with SketchUp ("Components", "Materials" and "Styles") out of the Program Files directory and placed them in the ProgramData directory.
In addition they implemented user "Components", "Materials", "Styles" and "Templates" folders.

It seems like a table would be a nice addition to the documentation for file locations.

Because that is what they were originally named, and their name was changed in the GUI interface and help files, but there was not a good reason to change the class name. I generally refer to them as “scene pages” to cover both names.

2 Likes

Module: UI — SketchUp Ruby API Documentation

UI.menu('File').add_item('New from Nifty template',1) {
   MyModule::MyPlugin.open_new_nifty_model()
}

The position integer argument is undocumented, and could be removed in later versions.

It works on Windows, but I do not know if it works on Mac.

2 Likes

It works on the mac too.

Again thank you all. Also for the other info. Not much knowing about the past, this is good info.

Ouch! I did test when there was always a model.skp open.
The menuItems are disabled when there is no document open.

Is there a way ‘hidden/undocumented’ to enable my ‘New…’ menu, when there is no document open.

unless file_loaded?(__FILE__)
      menu = UI.menu("File")
      mItem = menu.add_item("New...",1) { TemplateSetManager::getTemplates() }
      menu.set_validation_proc(mItem) { self.available? ? MF_ENABLED : MF_GRAYED }
      # always enable menu item
      # How???
      file_loaded(__FILE__)
end

Any suggestions?

Most menu items in SketchUp are disabled unless there is a model open - including items for built-in commands and Tools. Sorry, so far as I know there is no workaround. Why do you need to run your command with no model open?

Because it’s a command to start a new model from a chosen template.

Which, BTW, I logged a feature request for long ago.
It is long overdue that SketchUp got a Template wizard / manager like office apps do.

Three cheers for @rvamerongen for coding such a plugin ! :clinking_glasses:

1 Like

I am creating my own template manager.
One reasons is; I want to separated al the templates in groups, like a group for site plans, concept e.t.c, a group for 3D-printer modelling, one for the default SU templates.

Second ; If I open SU I get the start window then I can choose from a cluttered table of templates. After I choose one or open a recent document, and close that I have to go to the preference window to open a new template. Who did put it there!!! Has nothing to do with preferences. I just want to open a new document build from a template. So, or ‘New’ should be 'New…" and open a dialog with templates or I have to make one bij myself, where they are ordered by group.

It does because that function is setting the default template for SketchUp’s “New” command.

No New should remain New (as it is for quickly starting a new model from a user’s or company’s normal [default] template. Ie, some companies will enforce a certain template that employees must use.)

But (as I said above) we should have long ago had a “New from template…” command that opened a template manager like all the office suites have.

Pro users usually uncheck the box so that the Welcome dialog does not show on startup.

This must be a Mac only thing. This will not happen on Windows. But then again Windows always has a model open, and only 1 model open.

Actually there is a standard procedure. You enable AppObserver functionality for your plugin submodule.
Observers do not need to be a class object, nor even a subclass as the examples show.
Observers are abstract so any Ruby object can be an observer if it has the correctly named - publicly accessible callback methods.

# encoding: UTF-8

module RvAmerongen
  module TemplateSetManager

    extend self

    NEW_FROM_TEMPLATE ||= "New ..."

    @@menu_loaded = false unless defined?(@@menu_loaded)
    @@manager_open = false unless defined?(@@manager_open)
    @@manager_menu ||= MF_ENABLED

    #{# AppObserver callbacks
    #
      def expectsStartupModelNotifications
        return true
      end

      def onNewModel(model)
        build_menu_item()
      end

      def onOpenModel(model)
        build_menu_item()
      end
    #
    #}#

    def build_menu_item
      unless @@menu_loaded
        menu = UI.menu("File")
        mItem = menu.add_item(NEW_FROM_TEMPLATE,1) { open_manager() }
        menu.set_validation_proc(mItem) { @@manager_menu }
        # Don't load the menu item again ...
        @@menu_loaded = true
        # We are now done with the AppObserver ...
        Sketchup.remove_observer(self)
      end
    end

    def get_templates
      # build list of templates
    end

    def open_manager
      @@manager_menu = MF_GRAYED
      # create the WebDialog here...
      @@manager_open = true
    end

    def on_close_manager
      @@manager_open = false
      @@manager_menu = MF_ENABLED
    end

    unless @@menu_loaded
      # Always enable menu item, How ???
      # By using an AppObserver object, this module will do.
      Sketchup.add_observer(self) # (self is this module)
    end

  end
end

ADD: I discourage becoming hooked on any of the global methods in the "sketchup.rb" file.
Most are slowly being deprecated anyway. You might just as well use your own internal functions.
This is why I use and promote a internal reference to hold whether menu commands have been loaded, etc.

1 Like

Yeah, it’s a Mac thing, part of its app-centric design. Since OS X is willing to keep an app alive when the app has no document open, the system disables document-targeted menu items unless there is a document open. In SketchUp the only ones that are active are on the SketchUp menu (e.g. Preferences) and the ones on the File menu that will open a new or existing file. I don’t know whether an app can choose this behavior or if it is mandatory, but for the purpose here that’s academic because the SketchUp app would have to be programmed to provide it; a Ruby extension has no control.

But also, wouldn’t your extension have to somehow insert itself into the file opening process before SketchUp creates a model? On SketchUp Mac I don’t think this is currently possible because SketchUp opens the first blank model window before it loads Ruby extensions. Once upon a time SketchUp did it in the opposite order, loading extensions before opening the first model window. But this caused issues with initializing many extensions (for example anything that tries to access Sketchup.active_model for any reason), so it was reversed.

Purely as a matter of information, the behavior of staying alive when no document is open is voluntary, not mandatory. There is a simple delegation method that, if implemented, can tell OS X that the app wants to quit when its last document is closed. But there is a tradition of not implementing this method.

1 Like

Haha, Sorry but that makes no sense. So a user that makes every day or week a different kind of project and need a different template to start from but leave the check box marked are no Pro’s??

I agree that there should be a second New… must be, but if they want only one ‘new’ then they should change that. There are other options to create to lock users from unwanted behaviour, but to use a kind of lock for ‘some’ companies against the many Single users? Not very client friendly.
About requests. I understand that they cleaning up some mess from the early years, but there are enough one or two day jobs/bug to solve, but not seen or having any update since nov last year??? Like your request(s), some should be done in no time.

Its logical that items are disabled/greyed out when there nothing to do for the menu item command.
Ha funny, at the Mac you can open or new with the alt key to get a second tab with a second model, or thirth.

I will try your sample code, thank you for that.

1 Like

… and was why the expectsStartupModelNotifications AppObsever callback was created, to fix this loading issue.

I put this into the example above. Did either of you try it on the Mac ?

This is not what I meant. I meant that the majority start the same kind of project and use the same template the majority of the time.

I also …

(shrug) I quit wondering after 10 years.

1 Like

So there is some property that the application has to set to make certain menu items enabled when there is a blank workspace.

Hmm. But all is dandy if there is a model open, such as when SketchUp is started by clicking a SKP file ?