Override JavaScript Resource (eea.facetednavigation)

Hello everybody,

I am a new Plone developer and would like to customize the eea.facetednavigation for my product. In fact, we must set default search values ​​for text widgets in faceted view (not on the @@ faceted_configure page). I thought we need to add a set_default method to Faceted.TextWidget.prototype in the faceted-widgets-text-view resource (same as https://github.com/collective/eea.facetednavigation/blob/master/eea/facetednavigation/widgets/text/edit.js). Unfortunately, I do not know how to override Javascript resources in Plone, or whether there is a better way to set the default values ​​from faceted view without invoking the configuration page. Can someone help me please?

Welcome @brendaav! Ugh, you’ve embarked on what I fear is a quite complex task for a new developer.

Here is a good starting point, with the JS training class materials https://training.plone.org/5/javascript/index.html

There are many mentions of JS throughout our docs too, though I don’t have a suggestion for a particular starting point there: https://docs.plone.org/search.html?q=Javascript

I’m not familiar with the innards of eea.facetednavigation, but perhaps @avoinea could help

1 Like

hi @brendaav

these resources are registered as browser-resources. browser resources are references to files which are registered under an id and can physically be anywhere on the filesystem, where the python package can reach it. and you can override them.

note: in plone 5 we normally use plone.resource based resources, because they can even be stored in the ZODB, which browser-resources can't. but that's only a side note - eea.facettednavigation seems to only use browser-resources also for plone 5 - which is fine.

this is how the browser resource in question is defined:

you can override this definition in your package by using a browser layer:

<browser:resource
  name="eea.facetednavigation.widgets.text.edit.js"
  file="my_own_text_edit.js"
  layer="my.own.package.interfaces.IBrowserLayer"
  />

In Plone 4, your're basically done. Restart the Plone instance and put the js registry in ZMI in dev mode and back.
This is the Plone 4 js registry: https://github.com/collective/eea.facetednavigation/blob/7e0fd28f439a49da3beb0d012ae2ac0d1cd636eb/eea/facetednavigation/profiles/plone4/jsregistry.xml#L154

In Plone 5, you need to rebuild the bundle.
You need the plone-compile-resources script (in buildout added like it's done here: https://github.com/plone/buildout.coredev/blob/2956f4af6c24c8e7310f6fd09765734e2b6d6c75/core.cfg#L66 )
Then recompile: ./bin/plone-compile-resources -b BUNDLE_NAME
This is how the resource is registered in Plone 5:
https://github.com/collective/eea.facetednavigation/blob/7e0fd28f439a49da3beb0d012ae2ac0d1cd636eb/eea/facetednavigation/profiles/plone5/registry.xml#L366

Instead of the Browser Layer overriding you could also remove the resource from the resource registry and insert a new one (Plone 4) or use a different js file for the plone.resources/faceted-widgets-text-edit resource.

hope that helps.

3 Likes

Hi @brendaav

First of all, maybe you can detail more what is your use-case, because:

  • If you need to customize the default set of the widgets/facets when Faceted navigation is enabled (including the default values), you can provide a custom browser view on your add-on's layer like:

        <browser:page
          for="eea.facetednavigation.interfaces.IPossibleFacetedNavigable"
          layer="my.own.package.interfaces.IBrowserLayer"
          name="default_widgets.xml"
          template="template/default.xml"
          permission="eea.faceted.configure"
          />
    

    See https://github.com/eea/eea.facetednavigation/blob/master/eea/facetednavigation/browser/template/default.xml You don't have to write this XML by hand, you can use configure_faceted.html to define your facets and then use the Export button on this page.

  • Another way to set the default value, via JS this time, is to put it within the global query object Faceted.Query anywhere within your custom JS like:

    Faceted.Query['c4'] = ['Water'];
    

    Note: c4 is the id of your text widget.

  • Finally, if you really need to extend the JavaScript, even if you can override the entire JS file as @thet pointed out, you don't have to, as you can simply extend it within your custom JS file like:

    
    Faceted.TextWidget.prototype.set_default = function(element){
      console.log("Setting the default value");
    }
    

    Still, adding this method will not do the magic :slight_smile: as it's not an expected behavior.

3 Likes

Hi @thet

thanks for your reply :slight_smile:

I had to include the plone-compile-resources script as described here but then it works:
https://docs.plone.org/adapt-and-extend/theming/resourceregistry.html#compiling-bundles

After recompiling the bundle I had to create a new plone instance for the changes to take effect. Is this really necessary?

Maybe that's because the script throws an error:

nav@nav-ubuntu:~/allgmed-buildout$ ./bin/plone-compile-resources --site-id=allgmed -b faceted-widgets-checkbox-view
Setup npm env
Running command: npm install
Running command: /home/nav/allgmed-buildout/bin/instance run /home/nav/allgmed-buildout/eggs/Products.CMFPlone-5.1.5-py2.7.egg/Products/CMFPlone/_scripts/_generate_gruntfile.py
/home/nav/allgmed-buildout/eggs/plone.app.blob-1.7.4-py2.7.egg/plone/app/blob/content.py:23: DeprecationWarning: MimeTypeException is deprecated. Import from Products.MimetypesRegistry.interfaces instead
  from Products.MimetypesRegistry.common import MimeTypeException
/home/nav/allgmed-buildout/eggs/plone.portlet.collection-3.3.1-py2.7.egg/plone/portlet/collection/collection.py:2: DeprecationWarning: isDefaultPage is deprecated. Import from Products.CMFPlone instead
  from plone.app.layout.navigation.defaultpage import isDefaultPage
/home/nav/allgmed-buildout/eggs/Products.CMFPlone-5.1.5-py2.7.egg/Products/CMFPlone/browser/syndication/views.py:17: DeprecationWarning: wrap_form is deprecated. Import from plone.z3cform.layout instead.
  from plone.app.z3cform.layout import wrap_form
/home/nav/allgmed-buildout/eggs/psycopg2-2.7.6.1-py2.7-linux-x86_64.egg/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead. For details see: <http://initd.org/psycopg/docs/install.html#binary-install-from-pypi>.
  """)
_url
_setup_tables
_setup_mappers
/home/nav/allgmed-buildout/src-mrd/collective.lead/collective/lead/database.py:89: SADeprecationWarning: The 'transactional' argument to sessionmaker() is deprecated; use autocommit=True|False instead.
  sessionmaker(bind=engine, **self._session_properties))
/home/nav/allgmed-buildout/eggs/Zope2-2.13.27-py2.7.egg/OFS/Application.py:102: DeprecationWarning: Expected text
  transaction.get().note("Created Zope Application")
/home/nav/allgmed-buildout/eggs/Zope2-2.13.27-py2.7.egg/OFS/Application.py:267: DeprecationWarning: Expected text
  transaction.get().note(note)
/home/nav/allgmed-buildout/eggs/Zope2-2.13.27-py2.7.egg/OFS/Application.py:523: DeprecationWarning: Expected text
  transaction.get().note('Prior to product installs')
2019-04-17 18:13:12 WARNING PrintingMailHost Hold on to your hats folks, I'm a-patchin'
2019-04-17 18:13:12 WARNING PrintingMailHost 

******************************************************************************

Monkey patching MailHosts to print e-mails to the terminal.

This is instead of sending them.

NO MAIL WILL BE SENT FROM ZOPE AT ALL!

Turn off debug mode or remove Products.PrintingMailHost from the eggs
or remove ENABLE_PRINTING_MAILHOST from the environment variables to
return to normal e-mail sending.

See https://pypi.python.org/pypi/Products.PrintingMailHost

******************************************************************************

Using site id: allgmed
Target compile path: fetch from bundles
"allgmed" bundles compiles paths/filename
- css path: /home/nav/allgmed-site/src/allgmed/site/browser/static
- css name: allgmed-compiled.css
- js path:  /home/nav/allgmed-site/src/allgmed/site/browser/static
- js name:  allgmed-compiled.js
"faceted-edit" bundles compiles paths/filename
- css path: /home/nav/allgmed-buildout/eggs/Products.CMFPlone-5.1.5-py2.7.egg/Products/CMFPlone/static
- css name: faceted-edit.min.css
- js path:  /home/nav/allgmed-buildout/eggs/Products.CMFPlone-5.1.5-py2.7.egg/Products/CMFPlone/static
- js name:  faceted-edit.min.js
"faceted-jquery" bundles compiles paths/filename
- css path: /home/nav/allgmed-buildout/eggs/Products.CMFPlone-5.1.5-py2.7.egg/Products/CMFPlone/static
- css name: faceted-navigation-jquery.min.css
- js path:  /home/nav/allgmed-buildout/eggs/Products.CMFPlone-5.1.5-py2.7.egg/Products/CMFPlone/static
- js name:  faceted-navigation-jquery.min.js
"faceted-view" bundles compiles paths/filename
- css path: /home/nav/allgmed-buildout/eggs/Products.CMFPlone-5.1.5-py2.7.egg/Products/CMFPlone/static
- css name: faceted-view.min.css
- js path:  /home/nav/allgmed-buildout/eggs/Products.CMFPlone-5.1.5-py2.7.egg/Products/CMFPlone/static
- js name:  faceted-view.min.js
"jqueryui" bundles compiles paths/filename
Missing resource type
- css path: None
- css name: collective.js.jqueryui.custom.min.css
Missing resource type
- js path:  None
- js name:  collective.js.jqueryui.custom.min.js
Traceback (most recent call last):
  File "/home/nav/allgmed-buildout/parts/instance/bin/interpreter", line 322, in <module>
    exec(_val)
  File "<string>", line 1, in <module>
  File "/home/nav/allgmed-buildout/eggs/Products.CMFPlone-5.1.5-py2.7.egg/Products/CMFPlone/_scripts/_generate_gruntfile.py", line 436, in <module>
    'in {}'.format(bundle.__prefix__))
KeyError: 'Missing or empty <value key="csscompilation" /> in plone.bundles/jqueryui.'
Traceback (most recent call last):
  File "./bin/plone-compile-resources", line 247, in <module>
    sys.exit(Products.CMFPlone._scripts.compile_resources.main())
  File "/home/nav/allgmed-buildout/eggs/Products.CMFPlone-5.1.5-py2.7.egg/Products/CMFPlone/_scripts/compile_resources.py", line 154, in main
    args.compile_dir
  File "/home/nav/allgmed-buildout/eggs/Products.CMFPlone-5.1.5-py2.7.egg/Products/CMFPlone/_scripts/compile_resources.py", line 56, in generate_gruntfile
    subprocess.check_call(cmd, env=os.environ)
  File "/usr/lib/python2.7/subprocess.py", line 190, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['/home/nav/allgmed-buildout/bin/instance', 'run', '/home/nav/allgmed-buildout/eggs/Products.CMFPlone-5.1.5-py2.7.egg/Products/CMFPlone/_scripts/_generate_gruntfile.py']' returned non-zero exit status 1

Can you help me with that?

Found out that I have to remove the resource from the bundle in the resource registry and add it again.

Look like there is a problem with a jqueryuy bundle:
KeyError: 'Missing or empty <value key="csscompilation" /> in plone.bundles/jqueryui.'

Removing/Adding Plone Sites or resources shouldn't be necessary. But you need to:

  • increase the last_compilation date of the compiled bundle
  • set the resource registry into development mode and back from development mode once, so that the new bundles are applied.
1 Like