<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">H Henning,<div class=""><br class=""></div><div class=""><br class=""><div><blockquote type="cite" class=""><div class=""><div class="">Interesting approach. It seems even the blog you mention agrees with you when saying "[...] so we had to help all developers apply the filter. That is one downside: it’s totally quiet, so failures aren’t readily surfaced." :-)<br class=""></div></div></blockquote><div><br class=""></div><div>Exactly. It somehow always felt wrong.</div><div>Especially Devs not familiar with Geonode had a hard time understanding what </div><div>is going on ;))</div><br class=""><blockquote type="cite" class=""><div class=""><div class="">However, I still assume changes in your working copy<br class=""></div></div></blockquote><div><br class=""></div><div>Correct, I also have to make some small tweaks in my working copy.</div><div>But trying to keep them as simple as possible:</div><br class=""><blockquote type="cite" class=""><div class=""><div class="">- INSTALLED_APPS </div></div></blockquote><div><br class=""></div><div>I did not touch settings.py except having the following in the end:</div><div><br class=""></div><div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(64, 11, 217);" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""># custom settings</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(193, 101, 28);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">try</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">:</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #c814c9" class="">from</span><span style="font-variant-ligatures: no-common-ligatures" class=""> .my_custom_settings </span><span style="font-variant-ligatures: no-common-ligatures; color: #c814c9" class="">import</span><span style="font-variant-ligatures: no-common-ligatures" class=""> *</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(47, 180, 29);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #c1651c" class="">except</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">ImportError</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">:</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #c1651c" class="">pass</span></div></div><div><br class=""></div><div>Doing so I can extend and override what ever I need like INSTALLED_APPS, but keep the rest of settings untouched.</div><div>Of course only things get into my_custom_settings that cannot be configured via .env anyways</div><div><br class=""></div><div><br class=""></div><div><blockquote type="cite" class="">- docker/-compose files<br class=""></blockquote><div><br class=""></div><div>Similar as with settings I do override certain parts with a custom compose file</div><div><br class=""></div><div>docker-compose -f docker-compose.yml -f docker-compose-custom.yml up -d</div><div><br class=""></div><div><a href="https://docs.docker.com/engine/reference/commandline/compose/#use--f-to-specify-the-name-and-path-of-one-or-more-compose-files" class="">https://docs.docker.com/engine/reference/commandline/compose/#use--f-to-specify-the-name-and-path-of-one-or-more-compose-files</a></div><div><br class=""></div><div>Doing so docker-compose.yml can stay as</div><div><br class=""></div><div><br class=""></div></div><blockquote type="cite" class=""><div class=""><div class="">or requirements.txt<br class=""></div></div></blockquote><div><br class=""></div><div>Good point! I’ve just changed it and left a comment before my changes.</div><div>But I guess it should also work to mount your requirements into the container</div><div>and override the start command a bit:</div><div><br class=""></div><div>entrypoint: ["/usr/src/geonode/entrypoint.sh", "bash", "-c", "pip install --no-cache-dir -r custom_requirements.txt && uwsgi --ini /usr/src/geonode/uwsgi.ini“]<br class=""><br class=""></div><div>(Untested, and leaving a comment in requirements.txt might be cleaner in that case ;)</div><br class=""><br class=""><blockquote type="cite" class=""><div class=""><div class="">These changes can be kept at a minimum and probably in a local branch, of course. Did you also try different approaches with regard to customizing geonode-mapstore-client, or do you prefer programming a completely different UI (probably this depends ;-))?<br class=""></div></div></blockquote><div><br class=""></div><div>To be honest, I have blocked adaptations for clients here as much as possible. Mainly because the reactive part of mapstore2 doesn't make it easy to develop (but that's due to my lack of knowledge).</div><div>Also maintaining a fork is something I like to prevent.</div><div><br class=""></div><div>In some cases I have developed small custom viewers that only have geonode as a data provider.</div><div>In one particular case, I decided to listen for WFS requests, process them as needed and create some DOM elements. This is of course a very messy solution as the virtual DOM should not be touched. But in this case it could be accepted and I avoided a custom build ;) To get the idea.</div><div><br class=""></div><div><br class=""></div><div><div> // Catch WFS request</div><div> var elements = [];</div><div> (function() {</div><div> var origOpen = XMLHttpRequest.prototype.open;</div><div> XMLHttpRequest.prototype.open = function() {</div><div> this.addEventListener('load', function() {</div><div> if (this.responseText.includes(’something')){</div><div> window.items = JSON.parse(this.responseText);</div><div> do_something()</div><div> }</div><div><br class=""></div><div> });</div><div> origOpen.apply(this, arguments);</div><div> };</div><div> })();</div></div><div><br class=""></div><div><br class=""></div><div>…</div><div><br class=""></div><div><div>// Create the button that opens the compare tool</div><div>waitForElm("#drawer-menu-button").then((elm) => {</div><div> console.log(„mapstore is ready“);</div><div> // I guess there is a mapstore event we can listen on ...</div><div> drawer = document.getElementById("mapstore-drawermenu");</div><div> var i = document.createElement("i");</div><div> i.classList.add("bi", "bi-arrow-left-right", "switch_icon");</div><div><br class=""></div><div> var _button = document.createElement("button");</div><div> _button.setAttribute("id", "compare_button");</div><div> _button.setAttribute("data-bs-toggle", "offcanvas");</div><div> _button.setAttribute("data-bs-target", "#offcanvasRight");</div><div> _button.setAttribute("aria-controls", "offcanvasRight");</div><div><br class=""></div><div> _button.appendChild(i);</div><div> _button.classList.add(</div><div> "square-button",</div><div> "ms-drawer-menu-button",</div><div> "btn",</div><div> "btn-primary"</div><div> );</div><div> drawer.appendChild(_button);</div><div>});</div><div><br class=""></div><div>and so on. Again this is of course a no no ;)</div></div></div><br class=""></div><div class="">Hope this helps,</div><div class=""><br class=""></div><div class="">Cheers </div><div class=""><br class=""></div><div class="">Toni</div><div class=""><br class=""></div></body></html>