• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Pass json object from JSX file to c++ plugin and return an array of json object from c++ plugin

Contributor ,
Dec 04, 2022 Dec 04, 2022

Copy link to clipboard

Copied

Hi All,

 

I am looking for a solution in which I can pass  json object as an argument to a scriptable method

I went through the scriptable plugin architecture and created a scriptable resource and added a method on document object as follows

resource VersionedScriptElementInfo(1)
{
//Contexts
{
kCS2ScriptVersion, kCoreScriptManagerBoss, kWildFS, k_Wild,
}
{
Method
{
kTestApplyScriptElement,
e_TestApplyTag,
"apply tag",
"Apply the tag",
Int32Type, // status code
"Status: 0 if ok, non-zero if error"
{
p_TagInfo, "tag info", "tag info ...", RecordType(kAnyObjectScriptElement), kRequired,
}
}

// Connects this plug-in's text attribute to scripting and INX round trip.
Provider
{
kTestProviderBoss,
{
Object{ kDocumentObjectScriptElement },
Method{ kTestApplyScriptElement }
}
}
}

 

my provider file look like as follows

=====

ErrorCode TestProvider::HandleMethod(ScriptID methodID, IScriptRequestData* data, IScript* script)
{
ErrorCode status = kFailure;
do {
switch (methodID.Get()) {
case e_TestApplyTag:
status = this->ApplyTag(data, script);
break;
default:
status = PrefsScriptProvider::
HandleMethod
(propID, data, script);
;
}
 
} while(false);
 
return status;
}

=====

Now what code I should write in TestProvider::ApplyTag to get the key value pair of json object which I send from jsx file while calling this function.

 

code in jsx file is look like as follows

function test() {

var info = {};

info["name"] = "abc";

info["id"] = "1";

info["address"] = "abc xyz";

info["code"] = "w12";

app.activeDocument.applyTag(info)

}

 

Please help me to get solve it.

 

Regards,

Alam

TOPICS
SDK

Views

742

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Contributor , Dec 06, 2022 Dec 06, 2022

I achieved my goals by making following changes.

p_TagInfo, "tag info", "tag info ...",  VariableArrayType( kVariableLength ){ StringArrayType(2) }

and use CusDtLnkOptionScriptProvider.cpp for storing data and fetching it.

in jsx file I pass data as follows

var testData = [];

testData.push(["key1", "val1");

testData.push(["key2", "val2");

app.activeDocument.applyTag(testData)

Votes

Translate

Translate
Contributor ,
Dec 05, 2022 Dec 05, 2022

Copy link to clipboard

Copied

Is it possible to pass json object from jsx scripts to c++ plugin? if yes then what scriptDatatype I need to use in fr file and how to extract value in provider.cpp file.

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Dec 05, 2022 Dec 05, 2022

Copy link to clipboard

Copied

JSON is a set of conditions that applies to a string. You can pass strings thru the scripting glue, but those JSON conditions are not enforced. At the C++ side, you'd also have to write your own parser or use e.g. the one provided by boost.

 

You can not pass arbitrary plain objects - property names must be predeclared in a ScriptInfo resource of any plug-in, the glue code will map the name to a ScriptID using the ScriptInfo database.

 

When you declare something to be RecordType(yourObjectType), that means the record is to be validated to use only properties from yourObjectType . I don't know whether there is any magic script element ID to accept arbitrary records, your RecordType(kAnyObjectScriptElement) is not used in the application itself. How did you come to that idea?

 

Anyway, if it works, your method (in the script provider) would have to extract the argument from its ScriptRequestData (ask for p_TagInfo). That would copy the value into a ScriptData. You can examine the ScriptData, ask whether it is indeed a record then extract that into a ScriptRecordData and iterate further on.

 

If your generic record approach fails, the closest you can get with a scriptable plug-in is to use AnyType instead of that RecordType. For a JavaScript object you'd receive a record with the subset of keys where the name could get found, other properties are just omitted. Of course AnyType would also accept other types (strings, numbers, arrays, native objects etc.), you'd have to weed them out yourself.

 

Another alternative could be the separate ExtendScript SDK resulting in an ExternalObject, with the disadvantage that ExternalObject is likely not supported in UXP scripting and the SDK is for thrill seekers at best. The SDK used to ship with ESTK, but nowadays the best bet would be the developer downloads of Bridge (the CC app). Be warned that it took me several days to get something going with it and it has many other limitations.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 05, 2022 Dec 05, 2022

Copy link to clipboard

Copied

I try to use following api in provider class to fetch data that is send from jsx file.

const ScriptRecordData props = data->GetRequestData() ; and iterate it as follows

for ( ScriptRecordData::const_iterator iter = props.begin() ; iter != props.end() ; ++iter )
{

// but iter->Key() returns me scriptId not json key

// I could not debug the plugin because on xcode debug is not working an alert is shown when try to attach.

}

 

Do I need to follow the approach that is shown in snippetrunner plugin that for kSnpRunnableObjectScriptElement has some properties and for each property they used IStringData or IStringListData

and for my requirments where I have json objects tof 10-12 properties and need to pass that object into scriptable method, Do I need to add 10-12 IStringData interface to my boss class?

and also do I need to inherit my provider class with RepresentScriptProvider.?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 06, 2022 Dec 06, 2022

Copy link to clipboard

Copied

Moreever in context of snippet runner plugin. in fr file there is a comment that

p_SnpRunnableName is bind to IID_ISNIPPETNAME, where is this binding code written?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Dec 06, 2022 Dec 06, 2022

Copy link to clipboard

Copied

In your ScriptInfo resource you declare the arguments of your method - namely p_TagInfo . You access the passed argument by that ScriptID using ExtractRequestData(). I already mentioned that above (extract the argument using its ScriptID).

With GetRequestData you get a record of all provided arguments where the argument ScriptID is the record key. Note that some arguments may be optional (see ScriptInfo resource) and missing if not provided by the caller at the JS side.

You should not need to attach Xcode, just launch the plug-in from within:

Go to Product >> Scheme >> Edit Scheme ... , in the "Run" panel, "Info" tab point to the appropriate executable.

Then launch InDesign from within Xcode.

 

When you follow snippet runner by implementing an own object matching kSnpRunnableObjectScriptElement, you will need a RepresentScriptProvider or something derived. When you just add a method somewhere else, you can stick to a smaller implementation. The use of these string interfaces is an implementation detail of SnippetRunner, not a requirement.

I'm not using SnippetRunner myself, so leaving further details to others. Anyway if I search the SDK with a good editor (excluding Xcode for that task, better have a look at BBEdit or others) there are several hits on IID_ISNIPPETNAME or p_SnpRunnableName. This is about a property of the snippet object, though while above we were talking about a method.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Dec 06, 2022 Dec 06, 2022

Copy link to clipboard

Copied

Regarding ScriptID vs. JSON key, I also mentioned above that the scripting glue is working on ScriptIDs. It is easier to compare 32 bit integers rather than strings, so all the example code is referring to p_someProperty and m_someMethod for a reason. Also, the mapping must be declared in the ScriptInfo resource, otherwise the particular property will be lost in your call.

If you really need to translate the ScriptID back to a string e.g. for debug output, you have to get hold of the appropriate ScriptInfoManager (see IScriptUtils) - the names are formatted differently per scripting language e.g. AppleScript may break them up using spaces instead of camelCase, while VBScript may use CamelCase ...

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 06, 2022 Dec 06, 2022

Copy link to clipboard

Copied

I achieved my goals by making following changes.

p_TagInfo, "tag info", "tag info ...",  VariableArrayType( kVariableLength ){ StringArrayType(2) }

and use CusDtLnkOptionScriptProvider.cpp for storing data and fetching it.

in jsx file I pass data as follows

var testData = [];

testData.push(["key1", "val1");

testData.push(["key2", "val2");

app.activeDocument.applyTag(testData)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 06, 2022 Dec 06, 2022

Copy link to clipboard

Copied

Thanks Dirk for your reply it helps me in analysis.

on XCode debugging.

After setting InDesign.exe in - Product >> Scheme >> Edit Scheme ... , in the "Run" panel,

Could not find any menu action which launch InDesign.

What menu action in XCode I need to use for launching InDesign

 

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Dec 07, 2022 Dec 07, 2022

Copy link to clipboard

Copied

In the right "Info" panel see Executable "Adobe InDesign 2022.app". You can change the executable via the dropdown's "Other..." . As a result, the top left icon should become that of InDesign, also in Xcode's project window.Bildschirmfoto 2022-12-07 um 13.24.03.png

 

Xcode >> Product >> Run should then launch InDesign, the same way as the triangle button.

 

Note that different from the example projects I use InDesign version specific build configurations so I can support multiple versions with the same project. You can keep that to the typical pair of release/debug.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 07, 2022 Dec 07, 2022

Copy link to clipboard

Copied

LATEST

I followed same approach as you mentioned but application did not launched.

I am attaching screenshot here

Screenshot 2022-12-08 at 11.22.26 AM.png

 

Only difference is that I try with Release build as I don't have InDesign debug version.

My XCode version:- 14.1

OSX - 12.6

InDesign Version- CC2022

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines