View on GitHub

sketchup-react-demo

An example for the use of React.js with SketchUp's UI::HtmlDialog

Download this project as a .zip file Download this project as a tar.gz file

« Index Creating a basic React.js project »


Structure of the SketchUp Extension

Before we dive into the Javascript side of things, let’s set out the basic file structure for the extension:

+- sketchup-react-demo.rb
+- sketchup-react-demo/
|  +- main.rb
|  +- dialog.rb
|  +- html/
|  |  +- index.html
|  |  +- static/
|  |  |  +- css/ 
|  |  |  +- js/
|  |  |  +- media/
|  |  +- [other html related files]
|  +- [other Ruby related files]

At the top level we have a sketchup-react-demo.rb file which will register the extension. See the extension example in the Sketchup Ruby API documentation for details. Next to the file we have a sketchup-react-demo directory with all the files related to our extension (Ruby scripts and others). By convention the names of the Ruby file and the extension directory should match.

html/

All files for the HTML and Javascript content of the HtmlDialog are kept in the html directory. The files and directories within html will be generated by the React.js build scripts. In a production build these will be minified and versioned so there is no option for manual changes.

The challenge is to set up our React.js project in a way that allows us to copy the finished production-ready app into this directory without further modification. We will discuss how to accomplish this during the setup of a basic React.js project. That way we can use the React.js development environment to work on the HTML content and don’t have to go back and forth between Ruby and Javascript.

main.rb

On the Ruby side you will most likely have a file to do the initial setup of your extensions’s functionality. Here you typically load other Ruby files and create entries in the SketchUp menu for your features. For our basic app we just load the file dialog.rb and create an entry in the Extensions menu to show the HtmlDialog window.

# sketchup-react-demo/main.rb
$:.push(File.dirname(__FILE__))
require 'dialog.rb'

module SketchupReactDemo
  module_function
  def addMenu
    plugins = UI.menu("Extensions")
    plugins.add_item("SketchUp React Demo") { SkethupReactDemo::show_dialog }
  end
end

# create menu entry only the first time the file is loaded
if (not file_loaded?("sketchup-react-demo"))
  SketchupReactDemo::addMenu()
  file_loaded("sketchup-react-demo")
end   

dialog.rb

In the dialog.rb file we create and show the HtmlDialog window. Some additional magic needs to happen here because SketchUp uses a temporary directory as the base for any HTML content. This will break paths to images and other files that we want to included in our dialog.

We need to set an explicit <base href="..."> tag in the header with the full path to the directory that contains our HTML files. When we set up our React app we will add a placeholder (BASEURL) for the base url path to the index.html template. Then we can use Ruby to read this file as a string and substitute the BASEURL placeholder with the full path of our extension directory.

# sketchup-react-demo/dialog.rb
module SketchupReactDemo
  module_function

  def show_dialog
    # load html from index.html and replace BASEURL with
    # the path to the current directory
    basedir = File.dirname(File.expand_path(__FILE__))
    html = File.read(File.join(basedir, "html", "index.html"))
               .sub("BASEURL", basedir)

    # set options
    options = {
      :dialog_title => "Sketchup React Demo",
      # more options
      :style => UI::HtmlDialog::STYLE_DIALOG
    }
    
    # create and show the UI::HtmlDialog instance
    dlg = UI::HtmlDialog.new(options);
    dlg.set_html html
    dlg.show

    # return dlg instance for interaction at Ruby console
    return dlg
  end
end

The last return statement returns the dialog. We can use this to invoke the show_dialog function from the Ruby console and interact with the returned dialog instance.


« Index Creating a basic React.js project »