Step 1: Create a class to output the javascript
I created a file in src/my.product/my/product/browser called CommonUtils.py and added a class GlobalJS with a __call__ method that returns a string containing the javascript. __call__ sets the content-type, creates the string containing the variable, and returns the string.
class GlobalJS(BrowserView): def __call__(self,REQUEST,RESPONSE): RESPONSE.setHeader('Content-Type', 'application/javascript') js_string = "var portal_url = '%s';" % (self.context.portal_url()) return js_string
Step 2: Create a browser view pointing to the class
In src/my.product/my/product/browser/configure.zcml, I added a browser view pointing to GlobalJS, gave it a name, and added a permission. Note that the name of the file containing GlobalJS is CommonUtils.py
<browser:view for="*" name="global_js.js" class=".CommonUtils.GlobalJS" permission="zope2.View" />
Step 3: Register the view in javascript registry
Here, I register the browser view in src/my.product/my/product/profiles/default/jsregistry.xml. I needed access to portal_url before jquery was loaded, so I added the insert-before property. Note that the id is the same as the name registered in the browser view.
<javascript id="global_js.js" cacheable="True" compression="safe" cookable="True" enabled="True" expression="" inline="True" insert-before="jquery.js"/>
Now, global_js.js is loaded on every page and I have access to portal_url from within javascript.
Hope this helps someone.