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