How to write portable image paths in CSS files for a mounted sinatra app? - sinatra

Background
You are writing a sinatra (or rack) application, and want to be able to use it, with no code changes, both as a standalone app, or as a mounted app.
That is, you might run this application on its own, or you might mount it as a sub-application inside some other app, by doing the following in your "config.ru":
run Rack::URLMap.new("/" => MainApp.new,
"/my_mounted_app" => MountedApp.new)
Everything seems to be going well, since you are careful to use sinatra's url() helper in all your views, ensuring that the correct paths will be generated regardless of how or if your app is mounted.
The problem
But now you want to include an image as a background in a CSS file, and you run into a dilemma:
Use the url() helper method inside your CSS file. This ensures your image paths are correct and portable, but now your CSS file has to be processed by sinatra on every request.
Use a build process, perhaps involving SASS and some global config file which has the path your app is mounted to, to generate your CSS files with the correct image paths. This also ensures correct paths, but introduces the complexity of a build process.
Is there a third, better option? Is the real problem mounting an app using URLMap -- is there another way to achieve mounting which avoids these problems?
Again, the goals are:
A fully portable app, which can be mounted without any changes.
Static assets that don't need to be processed by sinatra.
No static asset build process.

You can just use a relative URL in your CSS.
Since both the CSS and the image will be under the public dir the relative path between them will be the same wherever the app as a whole is mounted.

Related

how to bundle flutter desktop assets into a single file for production build

after building the flutter project for desktop, flutter copies all asset files inside the assets directory into the build/flutter_assets/assets which are easily accessible and modifiable (which is not secure at all!), user can change the whole images easily and do some kind of modding the app with no experience required! or even in the worst situation with modifying the AssetManifest he could change the runtime dynamic libs with the malicious libs and get a hook from the app.
most modern frameworks/languages have the option to embed the resources inside a single file (that makes it harder to modify the files / repack the resource file) for example C#(WPF/Win32) embeds the resources in the resource Resource section or even Electron (Javascript) embed the whole resources into a file (it's easy but better than nothing)
I didn't find any similar behavior in Flutter Desktop (Windows/Mac/Linux) is there any alternative for flutter?
For now [12/12/22] it seems flutter desktop won't use resources to bundle the resources into a single file.
So I've created two separate libraries to achieve this
https://github.com/kooroshh/bundler that compresses the whole given assets into a single file and encrypts it with AES-128
https://github.com/kooroshh/flutter_bundler that reads the bundle file from and decrypts it into the memory that can be used with Image.memory or Direct file access using Virtual Files.
I hope an official solution gets implemented in the flutter framework.

Can we overlay the file to our custom path

Can we overlay the file to our custom path or we have to overlay the file to exact folder structure location as in libs?
For example, I want to overlay the constants.js (/libs/cq/ui/widgets/source/constants.js) file, in this adobe recommended Copy this file to /apps/cq/ui/widgets/source/constants.js for overlaying, but in my project that folder structure is not there, so I have copied to the custom path in apps folder and tested the changes and overlaying is working fine.
The file needs to have the same path as the one in libs except for replacing 'libs' with 'apps'. It does not work with custom paths*. If the project does not already have the structure, you can always create it. Don't forget to update the META-INF/Vault/filter.xml file to register the new path with projects package definition.
*Technically you can change the configs to add new searchpaths. But do remember that you might have to share the AEM instance with different tenants and sticking to the usual conventions goes a long way in having a predictable setup. I honestly don't see a reason to do this, it is already an acceptable practice to overlay under '/apps'. The filters on package provide enough flexibility to get along with other tenants while modifying similar areas.
I think you want to create the overlay in your custom project under /apps. If my assumption is correct, then you can certainly do it.
Taking your example in consideration, /libs/cq/ui/widgets/source/constants.js can be overlayed to /apps/<your-project>/cq/ui/widgets/source/constants.js by adding an entry in the Apache Sling Resource Resolver Factory configuration.
See this answer for the detailed steps. I hope this helps.

How does GWT ClientBundle caching work?

I am trying to better understand the use of GWT ClientBundle and caching.
If I have a large text file, for example, that I'd like to make available to my client, I can use
public interface MyResources extends ClientBundle {
public static final MyResources INSTANCE = GWT.create(MyResources.class);
#Source("myText.txt")
public TextResource myText();
}
//-- then later to use the text
String text = MyResources.INSTANCE.myText().getText();
Does this mean that the file "myText.txt" would be downloaded from the server the first time the client runs the app, and then the file would be stored in the browser's cache so that in future uses of the app, the file does not need to be downloaded?
If so, what happens if I change "myText.txt", does the app know to get the new version?
Finally, if the file is indeed stored in the cache, how then is this different from local storage in HTML5?
Thanks.
As Daniel Kurka already mentioned, the resources can be inlined in the js file (a *.cache.* file) where the rest of the compiled GWT code lives.
Inlining does not occur for all resources in a client bundle. E.g. large images are never inlined, it can also be prevented with #ImageOptions.preventInlining(), and it doesn't occur for ExternalTextResources.
What's common for both cases is, that the results will be in *.cache.* files, with unique names that change automatically whenever the contents of a source file change (you'll have to recompile the GWT app though!)
This allows the server to deliver these files with appropriate caching HTTP headers (you'll have to set this up yourself!) For the client this means, that it will not only be able to cache the contents (which it does anyway, even if those headers aren't set), but it can even skip asking the server, if a newer version exists.
The big advantage of ClientBundles is, that the file names will change automatically. The biggest disadvantage is, that you must recompile your GWT app, when a resource changes. If you don't want that, then it's better to use some other approach to load the files: You can still make the browser cache any file you like (by setting the HTTP headers), but then you'll have to be careful to manually give them a new name, when the content changes.
You should use an External Text Resource if you want it to be loaded on demand and not as a part of compiled JavaScript.
https://developers.google.com/web-toolkit/doc/latest/DevGuideClientBundle#TextResource
If your users need the entire file, use one text resource. If users need parts of it, split this file into separate smaller files: only the requested file will be loaded when needed.
The external text resources can be cached like all other static files.
Files that are inside a clientbundle get inlined into your compiled javascript. They will not be downloaded separately. If you want to download a resource at a given time you can easily use request builder for that.
If you don`t want to download the file immediately but you still want to inline it, you can use code splitting and put the bundle into another part of your app.

Single image with GWT 2.4 requires an ImageResource?

I was just adding a single image to a GWT 2.4 application I was working on. I just put it under the images folder in the war and I had it working properly until I would compile it. Then it would get deleted from the folder. If I remember correctly, from working with older versions of GWT, you could just put an image in this folder to use it.
It just took a few minutes to convert the code to use an ImageResource, but do you have to use an ImageResource for just one image or is there another way to do this?
The class ImageBundle is deprecated, try to use ClientBundle instead.
Instead of putting the file in the war folder, which is typically generated, try putting it in a folder called public/ in the same directory as your client package. The compiler will move it then into your module directory.
And finally, ClientBundle (and ImageBundle, but don't use it) will automatically try to sprite your images where possible, and in some cases include the image in your main html download so that the user only needs to download and cache one large file instead of several files - even for individual images it can be worth it for repeat users of the page, to ensure that no caching issues ever occur.

Non class files with Java Web Start

How do you distribute other files needed by your application that aren't in a jar file? For example, the application at http://www.javabeginner.com/java-swing/java-swing-shuffle-game . The download contains Shuffle.jar, Shuffle.bat, Score.dat, and an images folder with 3 images in it. I can see possibly putting the images directly in Shuffle.jar, but you wouldn't want to put Score.dat in the jar file because it changes. Is there somewhere you could identify this type of file in the jnlp?
The non-java files should be stored as resources. For files that change, you store the original or template file also as a resource in your jar. When the program starts, you have it check the local system to see if that file exists. If not, it creates the local file by copying the template file from the JAR resource. If the file already exists, then it is used as is.
To save files to the local system, even when running in the sandbox (unsigned), you can use the PersistenceService (javadoc / example). If your java application is signed, then you can use the regular File apis to write the file to the local machine, such as in a ".yourgame" subfolder under the user's home folder.
You can put all those files (except the scores file) in your jar file and load the contents using resource loading.
I've just deleted and restarted my reply twice now, changing my answer each time; this is confusing and needs a bit more clarification.
Are you SURE that application is supposed to be a Web Start app? On the site you linked to, it doesn't appear to be. Are you trying to take an application that was not designed as a Web Start application and change it into one that can be Web Start?
If it's not a Web Start app as your tag implies, then this question is open ended. You can distribute it 100 different ways.
If you are indeed trying to convert it into a Web Start app, you can start by packaging the images into the jar and that will alleviate your first headache if you just read them from there instead of from a File(). If it's going to be Web Start, then you need to decide how you want to keep scores. You have to decide what the scoring system is like before you can decide on how to go about it; will all the scores be kept on the web site hosting the Web Start app? Will that part still be local? If you want to get access to the local file system, you need to sign the jar, then you can extract the score.dat to the file system and do whatever you want with it if the end user accepts.
You need to figure out what you want to do before you can do it, or at least clear it up for us if you already know more than we know you know.