Caching of QML files - qt

I use a common common.qrc module (with QML components and javascript code) that is linked against different plugins at different build times.
I must make sure that every plugin uses the version of the component it was designed with (at build time that is chosen).
In common.qrc I have
<qresource prefix="/Comp1Common">
<file alias="NotificationDrawer.qml">NotificationDrawer.qml</file>
<file alias="Drawer.qml">Drawer.qml</file>
</qresource
<qresource prefix="/Comp2Common">
<file alias="NotificationDrawer.qml">NotificationDrawer.qml</file>
<file alias="Drawer.qml">Drawer.qml</file>
</qresource
This way I can import in Comp1 the corresponding Common version (and that will not clash with the same common version of a component built at another time) by using
import Comp1Common
This is all good. But If I want to use singletons (still defined in common.qrc) defined as follows (in corresponding qmldir in common.qrc)
singleton Comp Comp.qml
Every time I would use Comp that is a singleton it would pick the first loaded version (for first loaded plugin) of that and not choose what is linked at build time in current plugin.
The described versioning works for non sigleton instances only.
LE: Further tests showed that normal instantiation (e.g Drawer.qml) is affected by cache also. The first component loaded by first plugin is used by second one.

Turns out I used aliases/prefix in a dumb way. The problem is that I needed the use a different prefix every time I updated my common.qrc. that way every plugin uses the local resources if import statement says it needs to use a specific version. Something like import CompCommonVx.

Related

Publishing Custom Elements, naming conventions, best practices?

I am about to make my Custom Element <card-t> public
pre-release is at: https://github.com/card-ts/playingcardts
Suggestions and enhancements much appreciated!
Couple of questions:
Naming Custom Elements
There is: https://www.webcomponents.org/community/articles/how-should-i-name-my-element
but it doesn't get past "must include a hyphen"
I went with element.card-t.js for sorting purposes.
Other best practices ??
Wrapping in IIFE & ES Modules?
The Custom Elements gets created in the Global Namespace, and doesn't return anything like a library does.
Wrapping in an IIFE should be enough?
Is there value in loading it as module?
<script type="module" src="element.card-t.js">
Extending Custom Elements
Should we by default return the class definition so extending is easier?
Since this is an opinion question these are my opinions:
Naming Custom Elements
I always name my JS file based on my class name and my class name is just the tag name but capitalized. So my tag <my-thing> would have a class name of MyThing and my filename would be components/MyThing.js
Wrapping in IIFE & ES Modules?
I create all of my code in ES6+ and then I create an additional ES5 CommonJS version and an ES5 IIFE version and let people load what they want.
I use rollup and my component-build-tools to create my various versions. component-build-tools component-build-tools also combines all dependencies of a component into the output file. This can lead to some replication, but most of the time that is small enough I don't mind.
My components end up with their templates and locale strings embedded into the published files. This is a feature of component-build-tools.
Extending Custom Elements
As a general rule I expose the class name in all three formats of my files. This does help with extending my components, yet I doubt that many people will ever want to do that.
Where to place the files.
The hardest thing is where to place the files so they are easily accessed by the web page.
I have a build step that copies my files from the node_modules folder into a dist folder. This was the easiest thing for me to know exactly where my files are located.
Doing this allows me to npm install anything and then still get their files into a location I know and can use. But it also has lead to me not worrying greatly about where my files end up in my repo.
I do tend to have a dist folder and in there I have:
dist
+- js
+- components
+- MyThing.js
+- MyThing.min.js
+- AnotherThing.js
+- AnotherThing.min.js
+- SoOn.js
+- SoOn.min.js

Can name from build.sbt depend on Activator name in activator.properties (or vice versa)?

Just noticed that there are two name settings in any Typesafe Activator template - one in build.sbt and another in activator.properties.
Is there a way to make one depend on (use the value of) the other? Although the build's name can be defaulted to the name of the main project folder, I'm not sure about the activator's.
You could make build.sbt write out or modify activator.properties, using whatever scala code you want to use for that.
But you'd still have to check activator.properties in to git because the Activator template-publication system does not run sbt on the project, it just looks at the files in git.
And also your nice template intended for end-users would end up with some extraneous build code in it to generate activator.properties, which would clutter up the example.
You could try going the other way but I think it won't work.
In sbt, name is a setting rather than a task, and is thus evaluated only once -- so if you made it read from activator.properties, you'd need to restart (or at least reload) your sbt build whenever you edited activator.properties. But you could read from activator.properties using whatever scala code you like. Something like:
name := {
val props = new java.util.Properties()
props.load(new java.io.FileReader(file("activator.properties")))
props.getProperty("name")
}
However, this is going to fail for two reasons.
When a template is instantiated (cloned) by an end user:
activator.properties is dropped
activator tries to replace the name in build.sbt with a user-selected one
So on clone, first the above code would fail due to missing activator.properties, and second the user's selected name wouldn't be swapped in (because the above expression is too complicated for activator to figure out how to replace it).
This name-replacement means your build.sbt name will get dropped in most cases anyway. The one exception is if the user downloads the "template bundle" (a pre-cloned zip of the project) from the template's detail page on typesafe.com, then the name in your build.sbt would be kept.
Note that if you ever change the name in activator.properties then you'd end up duplicating your template (you'd effectively be publishing a new template), so you may not want to abstract this anyway -- you should change it only when creating a new template is your intent.
Perhaps the bottom line is KISS -- write the name in two places. The alternatives are all going to cause headaches.
The only way I can think of to make this sane would be to have some code outside of the template which generated the template. Akka and Play both do this, I think, for templates that are part of the larger akka and play source trees. But at this point you're definitely doing more work than I'd do just to avoid copying one name string around, you'd want to have some other reason to go there.

plone:portlet vs plone:portletRenderer (subclassing problem)

A oddity we tripped across when upgrading sites from Plone 3 to Plone 4:
We define a number of custom portlets. One of these is a "Jobs" portlet which is a lightly customised News Portlet. This was subclassed from the News portlet, as suggested by:
http://plone.org/documentation/manual/developer-manual/portlets/appendix-practicals/subclassing-new-portlets.
That is:
<plone:portlet
name="falcon.JobsPortlet"
interface=".portlets.IFalconJobsPortlet"
...
renderer=".portlets.FalconJobsRenderer"
/>
where IFalconJobsPortlet subclasses from INewsPortlet:
from plone.app.portlets.portlets.news import INewsPortlet
class IFalconJobsPortlet(INewsPortlet):
"""Interface for Jobs portlet uses the same schema as News Portlet"""
We also (separately) want to replace the render class on the standard INewsPortlet, in
order to provide a custom template:
<plone:portletRenderer
portlet="plone.app.portlets.portlets.news.INewsPortlet"
class=".portlets.FalconNewsRenderer"
layer=".interfaces.IThemeSpecific"
/>
This works fine in Plone 3. This might just have been blind luck, or it
might be case that <plone:portletRenderer> used to run before
<plone:portlet>, and now run afterwards.
In Plone 4, falcon.JobsPortlet is set up correctly, but then <plone:portletRenderer>
kicks in and replaces the renderer clause, so that
".portlets.FalconJobsRenderer" (correct) is replaced with
".portlets.FalconNewsRenderer" (incorrect)
A solution/workaround in this case was simple: I stopped subclassing from
INewsPortlet, and just copied the schema across by hand from the original superclass:
class IFalconJobsPortlet(IPortletDataProvider):
"""Interface for Jobs portlet uses the same schema as News Portlet"""
count = ...
state = ...
My question, for future reference:
Is there a way to safely combine <plone:portlet> and
<plone:portletRenderer> when subclassed portlets are in play?
If you're not using layer="..." in your <plone:portlet name="falcon.JobsPortlet"...> registration, then this is probably the root. The ZCA, which this ZCML uses to register adapters, gives one lookup precedence over another based on interface specificity. So I'm guessing the since you give a layer in your <plone:portletRenderer> but not in your <plone:portlet> then the renderer in <plone:portletRenderer> matches the portlet interface of both and the layer is more specific and so it wins.
Since only <plone:portletRenderer> supports the layer specification, I would just add a <plone:portletRenderer> registration for the FalconJobsRenderer that is registered for the same layer and that will assure correct precedence. That way you can revert your workaround and subclass INewsPortlet. It is much more appropriate to subclass INewsPortlet.

Data models in Alfresco

I'm trying to create some data models in Alfresco.
I create an XML file in alfresco extension folder where I declare 3 types: one that extends cm:content and two others that extend the first one.
Then I create another XML file with the same namespace and declare there the fourth type.
Both files are included in the custom-model-context.xml and all the types are listed in the file web-client-config-custom.xml:
<content-types>
<type name="t3s:Document"/>
<type name="t3s:Document1"/>
<type name="t3s:Temp"/>
<type name="t3s:Temp1"/>
</content-types>
But in the Alfresco App I only see the last t3s:Temp1.
When I delete it and its XML-file I see all other types from the first XML file.
What does it mean and what do I must to change to see every type in Alfresco App?
You're only allowed to define a namespace in one model file. If you wish to use that namespace in a different model file, you need to import it, rather than trying to re-define it. From what you've said, I think you may be defining the same namespace in two places, so one overwrites the other.
You probably want to have a look through http://wiki.alfresco.com/wiki/Data_Dictionary_Guide and then tweak your setup so either everything is in one file, or otherwise you have one file define your namespace and the second imports it.

Eclipse/Flex: update a file every time I launch?

OK my project uses an xml file called Chart-app.xml inside this XML file there is a tag called <version></version> which I keep in the format like: <version>1.2.128</version> I am wondering if I can set it to append to the third number every time I run my project.
So if I ran it now it would be 1.2.129, then if i ran it again it would be 1.2.130
Thanks!!
After reading VonC's answer I don't know anything about ANT or creating custom builds, but he did give me an idea that seems to be working:
I already have a method to tell if the app is running in the ADL (within eclipse), so if it is, I just have my app open the file itself and change the value.
I am not sure there is a native Eclipse way to do this.
You can increment the number within that xml file either:
programmatically, launching a special class which do that, and then call your primary application Class
through a dependency during launch, for instance, you can make a JUnit test suite which will first call a Java class doing the increment, and then call your main method.
But in both case, you would have to somehow code the increment process.
Note: it is easier when you want to increment something each time you build, because you can add a custom builder.

Resources