Opening a maxon::URL in the browser: Anchors and query parameters?
-
Follow-up to: How do I open a maxon::Url in the default web browser?
Hi,
I am trying to open a maxon::URL in the browser. It basically works, but lacks essential support for HTML anchors (delimited with "#") and - even more important - does not seem to handle query parameters (starting with "?" and separated with "&") correctly by default.
Here is some code about the latter. I want to open the website where potential customers can request an activation key for my plugin:
// Build request query string maxon::BaseArray<maxon::String> urlQueryParts; if (licensingInfo.firstName.IsPopulated()) { urlQueryParts.Append("firstname="_s + licensingInfo.firstName) iferr_ignore(); } if (licensingInfo.lastName.IsPopulated()) { urlQueryParts.Append("lastname="_s + licensingInfo.lastName) iferr_ignore(); } if (licensingInfo.organization.IsPopulated()) { urlQueryParts.Append("organization="_s + licensingInfo.organization) iferr_ignore(); } if (licensingInfo.systemCode.IsPopulated()) { urlQueryParts.Append("inputcode="_s + licensingInfo.systemCode) iferr_ignore(); } const maxon::String urlQueryString(JoinElements(urlQueryParts, "&"_s)); // Build request URL maxon::Url url(GeLoadString(IDS_DEMOKEYGENERATORURL)); url.Set(maxon::URLFLAGS::QUERY, urlQueryString) iferr_ignore(); // DEBUG: Print URL to console maxon::String urlString = url.ToString(nullptr); GePrint(urlString); // Open URL in browser url.IoShowInOS(maxon::IOSHOWINOSFLAGS::OPEN_IN_EXPLORER) iferr_ignore();
The part with adding the query parameters to the URL works fine, even though I think it's quite a lot of code for something so simple. I'm doing it this way, because the SDK docs about
UrlInterface::SetUrl()
kind of hints to this.The
GePrint(urlString)
call prints the following:https://demo.mypluginsite.com?firstname=Arthur&lastname=Dent&inputcode=14004902462
So, that looks like exactly what I need. However, when calling
url.IoShowInOS()
, Safari tries to open this URL:https://demo.mypluginsite.com%3ffirstname=arthur&lastname=dent&inputcode=14004902462
And when I set my MacBook's default browser to Chrome instead, Chrome just opens a new tab at
about:blank
. This happens on my old macBook with El Capitan as well as on a new iMac with macOS Catalina.My questions:
- Why are the firstname and lastname values lower-case, and how can I prevent that from happening?
- Why is the "?" before the query parameters escaped, and how can I prevent that from happening?
- Why does Chrome not open the URL at all?
Thanks for help & advice!
Cheers,
Frank -
In Python, it's dead simple to open the default web browser with a URL and query parameters.
import webbrowser URL = "https://demo.mypluginsite.com?firstname=Arthur&lastname=Dent&inputcode=12312312320" webbrowser.open(URL)
Guess, if Maxon::URL can't do that, I'll have to write a Python plugin and call it from within my C++ code
Cheers,
Frank -
I ended up solving the problem with Python. Still, I would really appreciate some feedback from Maxon about why this doesn't work, if something can be done to fix it (and what), or a confirmation that it's actually a bug in Cinema. As things are now,
maxon::Url::IoShowInOS()
is not really usable to open URLs in the web browser. And that's a pity, because it would be really useful, too e.g. open a help website from within aPluginHelpDelegate
.Here's my solution (works in R20 - R23):
#include "ge_prepass.h" #include "operatingsystem.h" #include "maxon/vm.h" #include "maxon/cpython.h" #if API_VERSION >= 23000 // R23+: Load Python 3 #include "maxon/cpython37_raw.h" #else // Pre-R23: Load Python 2.7 #include "maxon/cpython27_raw.h" #endif #if API_VERSION >= 22000 #include "maxon/errortypes.h" #endif #include "c4d_general.h" #include "lib_py.h" /// /// \brief Simplified version of the ExecutePythonScript() example from the SDK docs /// maxon::Result<void> ExecutePythonCodeSimple(const maxon::String &code) { iferr_scope; // Check code if (code.IsEmpty()) return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION); // Create VM ref and scope #if API_VERSION >= 23000 const maxon::VirtualMachineRef& vm = MAXON_CPYTHON37VM(); #else const maxon::VirtualMachineRef& vm = MAXON_CPYTHON27VM(); #endif const maxon::VirtualMachineScopeRef scope = vm.CreateScope() iferr_return; // Init script iferr (scope.Init("Python Script"_s, code, maxon::ERRORHANDLING::PRINT, nullptr)) { const String errorMessage = "Error on Init()"_s; return maxon::UnknownError(MAXON_SOURCE_LOCATION, errorMessage); } // set __name__ = __main__ scope.Add("__name__"_s, maxon::Data("__main__"_s)) iferr_return; // executes the script and returns when it got executed. // info: if the script causes an unexpected infinite loop, Execute() does not return // and there is no way to stop from the outside. iferr (scope.Execute()) { const String errorMessage = "Error on Execute()"_s; return maxon::UnknownError(MAXON_SOURCE_LOCATION, errorMessage); } return maxon::OK; }
And I'm using it like this:
maxon::Result<void> OpenUrlInBrowser(const maxon::Url &url) { iferr_scope; maxon::String urlString = url.ToString(nullptr); // Build Python code maxon::String theCode; theCode = "import webbrowser\n"_s; theCode += "URL = \""_s + urlString + "\"\n"_s; theCode += "webbrowser.open(URL)\n"_s; // Execute code TF4D::Python::ExecutePythonCodeSimple(theCode) iferr_return; return maxon::OK; }
Greetings,
Frank -
Hi @fwilleke80 I can indeed confirm the issue, and I will create a bug report about it.
This is the mac only issue and with Chrome on Windows everything work as expected.Regarding your Python implementation, it's alright to do it as you did
Have a nice weekend,
Cheers,
Maxime. -
Thanks for confirming!
The strange thing is that I can reproduce this even in R20. Seems, not many people use this function to open URLs.
I'll mark this as solved then, as my solution presented in this thread works flawlessly on all R2x releases.
Cheers,
Frank