I explained this in the other topics I linked above.
(1) Load the .json
file into Ruby as a JSON String.
(2) Convert that JSON String into a Ruby Hash object using JSON.parse
.
(3) Then replace the %{hash_key}
parameters that you should have embedded into your HTML with the values from the data
hash, using the String#%
method.
In the snippet you posted above in post 3 , the line:
:json_data => File.read(File.join(path, "some_data.json"));
… should not be in the replacements
hash (looks like it was inserted and a comma does not follow it which would be a syntax error. The semicolon is not needed anyway.)
Instead, the data json should be loaded into a Ruby hash, like:
INCORRECT CODE (corrected below)
path = __dir__
# Load the stylesheet and javascript into a replacement hash:
replacements = {
:stylesheet => File.read(File.join(path, "stylesheet.css")) ,
:javascript => File.read(File.join(path, "javascript.js" )) ,
}
# Load the HTML text into a Ruby String:
html_text = File.read(File.join(path, "dialog.html"))
# Load the external JSON data file into a Ruby String:
json_data = File.read(File.join(path, "some_data.json"))
# Convert to a Ruby hash:
data = JSON.parse(json_data)
# Now replace the embedded %{hash_key} parameters in the HTML text.
# In your latest edition, the parameters within the HTML text should be:
# %{nam}, %{id1}, %{id2} and %{id3}
html_with_data = html_text % data
# Now replace the %{stylesheet} and %{javascript} parameters with the
# :stylesheet and :javascript values from the replacements hash into
# the HTML text and pass to dialog:
@dialog.set_html( html_with_data % replacements )
# Show the dialog:
@dialog.show
EDIT: The above (collapsed code) is actually incorrect. You cannot do replacements twice as I showed above because the first time a KeyError
exception is raised when the %{stylesheet}
and %{javascript}
parameters do not have matching keys in the data
hash.
Instead, we must merge the two hashes together and do the String#%
replacement operation ONCE.
Corrected code:
path = __dir__
# Load the stylesheet and javascript into a replacement hash:
replacements = {
:stylesheet => File.read(File.join(path, "stylesheet.css")) ,
:javascript => File.read(File.join(path, "javascript.js" )) ,
}
# Load the HTML text into a Ruby String:
html_text = File.read(File.join(path, "dialog.html"))
# Load the external JSON data file into a Ruby String:
json_data = File.read(File.join(path, "some_data.json"))
# Convert to a Ruby hash:
data = JSON.parse(json_data)
# Combine the data hash into the replacements hash:
replacements.merge!(data)
# Now replace the embedded %{hash_key} parameters in the HTML text.
# In your latest edition, the parameters within the HTML text should be:
# %{nam}, %{id1}, %{id2} and %{id3}
# This will also replace the %{stylesheet} and %{javascript} parameters
# with the :stylesheet and :javascript values from the replacements hash.
# Then pass the HTML text and to the dialog:
@dialog.set_html( html_text % replacements )
# Show the dialog:
@dialog.show
So within your HTML text, lets say you are using <input type="text">
…
<div id="form">
<input type="text" id="nam" value="%{nam}" />
<input type="text" id="id1" value="%{id1}" />
<input type="text" id="id2" value="%{id2}" />
<input type="text" id="id3" value="%{id3}" />
</div>
… and after the html_with_data = html_text % data
statement executes, the %{key}
parameters in the HTML text should be replaced with the values from the data
hash corresponding to its hash symbol keys, and the result assigned to the html_with_data
string.
You should not be hardcoding paths. Your extension should be in a subfolder of the “Plugins” path which is in the user’s %AppData%
path … if, …
… IF the data is extension / users specific but not model specific.
plugins_path = Sketchup.find_support_file('Plugins')
Also from a file in your extensions subfolder (beneath "Plugins"
) you could also do:
plugins_path = File.dirname(__dir__)
If the data is model specific, either it likely should be saved to model.path
or saved within the model itself as an attribute dictionary.
Going from JSON to attribute dictionary:
dict = model.attribute_dictionary('DaveStudys_DrawBoxWizard', true)
hash = JSON.parse( json_text )
hash.each { |key, value| dict[key]= value }
Going from existing attribute dictionary to JSON:
dict = model.attribute_dictionary('DaveStudys_DrawBoxWizard')
json_text = dict.to_h.to_json