Approach for building a Gallery of images (ParentalKey vs StreamField) - wagtail

I'm trying to decide between using ParentalKey or StreamField, in this case, with the purpose of adding an image gallery to a page.
We don't need any other information than the image itself (given that the image will be anyway a wagtailimages.Image model's instance, so the alt text is already handled there).
Any thoughts on what is better to make it easier for the editor to work even if maintaining around 50 images per page?
And about good practices and code maintainability?
Would you prefer a third party package for the image gallery? (even if that blocks you from upgrading to wagtail 4?)
Would your opinion change if instead of a single image, we needed some more fields?
Many thanks!

For an image gallery, the first recommendation would be to use the Collections feature. You can get pretty far with the nested collection system and even add extra meta data if needed by adding a model that relates to the collection.
If that is not suitable, ParentalKey/InlinePanel would be my next pick. For simple relationships you get all the benefits of StreamField such as re-ordering, add/remove items but with solid database integrity and usage stats working out of the box.
Only go to StreamField if you need to have optional data set against each image. For example if you have an image list but images could be an Image with a RichText OR just an image.
Unfortunately, managing large sets of images is not great (outside of collections) so you may find you need to build a seperate UI for this. If that ends up being the case you will find migration of data already in model relations being easier to do or maybe not even needed with something like ModelAdmin.
Hope it goes well, be sure to write a blog post about what you end up doing.

I would use the ParentalKey with InlinePanel for that. It shows you all the images as a list in a more compact way than the StreamField. One can reorder this list.
A StreamField is more expandable in the future. You could add new blocks, like videos or quotes or whatever at any point. If you define each block as StructBlock, you will be able to add whatever you want in the future to these blocks without loosing existing data (also true for the ParentalKey model).
I would not use Collections for image slideshows as you won’t be able to sort the imagas in a collection via the CMS, right? Collections are meant to keep order in the backend, I think.

Related

how to export react JS components to static html

are there any utilities or approaches to export regular react component into an email friendly static html?
for example i have a dashboard using react-table and would love it if there was a way to auto-magically translate that to static html i could insert into an email body.
i can think of a few approaches using a headless browser to render as pure html, but it would be awesome if there was a solution with more email friendly html
Because the layout of these gets fairly complex, it may also be advantageous to render page as image and insert that image into email body?
I only really know HTML Email, and basics of React - and SO is not great for recommendations of software type questions - so I'll just speak to the email side.
If you can get HTML, you need to consider a few things.
First, anything over two columns is likely to run out of space. You would need to consider a stackable column structure with repeated headers. That would require hiding the duplicated headers for desktop views, since the tables would be separate due to the way we do stacked columns in emails (as inline-blocks without media queries). See https://medium.com/#nathankeenmelb/bulletproof-responsive-datatables-in-html-emails-64248b9e18f5 for full details.
Second, only some approaches would work like that. Images then would be your go-to option. A nice output for table images would be:
<img src="https://via.placeholder.com/600x500" width="600" style="vertical-align:middle;width:100%;border:0">
The link goes to the image itself so you can zoom and move around easier, and get maximum realestate.
An alternative built on that idea would be to have a link from the image to landing page with full web capabilities. That would take longer to load, but may be well worth it.
Since that's probably the most viable, I'll explain these choices of attributes and styles:
Use the width attribute width="600" because that's what Outlook desktop uses
Use inline styles for those email clients that do not support <style> blocks
Vertical-align:middle (or display:block) removes the space underneath the image that some email clients add
width:100% makes it responsive to mobiles
border:0 ensures no border is shown because of the link
Third, datatables are so finicky and particular in HTML email. Each table is unique because they have different data in them that responds differently. In normal web design, you can just use a nice reset and get everything working without much thought. In HTML Email, everything needs to be inline, and supported, with fallbacks for those things that are unsupported. So even the core data often needs editing - e.g. if it has long URLs, emails or words you need to add a wrapping span with word-break CSS but also <wbr>s in the middle of it for some email clients to properly wrap.
Datatables don't often come up, and because of these considerations, it's hard to see how they could be automated easily - and hard to build a case for it financially.
On a related note, if you can show the information using card UI, that seems to me to be a much nicer, simpler, more accessible and easier to code solution than datatables. This is about taking the information and redesigning it into card blocks. I talk about that in detail here: https://medium.com/#nathankeenmelb/responsive-datatables-through-card-ui-design-for-email-aca6f3c395a2

Howto programmatically create a PDF from a predesigned template made in InDesign

The goal is to design beautiful templates in InDesign, which are then being used to programmatically generate printable PDFs within a special application connected to a database, so I can fill data from the database into the templates.
I have no idea how to approach this. I found a lot of HTML to PDF conversion related info, but that approach has its limitations.
Did anybody face the same question and might point me in the right direction?
Yes, the scenario you described can be fully handled by InDesign Scripting using ExtendScript. I have done this in the past several times and it works quite well. The key in my opinion is to have a designer prepare the file for you as finished as possible and make good use of the built in InDesign automations. That means they will do the layout, but also set up all the paragraph styles, character styles, object styles and possibly grep styles as well as master spreads for each different page.
Then the job of the script that you run will mostly be to fill in the contents and to assign the mentioned styles and master spread as needed. If everything is set up properly, most of the layout should fall into place automatically.
Also, contrary to the comments to your question, I don't think you need InDesign server for that. Especially if you run everything locally anyways.

Should we create custom pages for all objects?

I noticed that salesforce doesn't allow to override control function for all objects.
Say if you want to do something whenever objects get saved there is no way to attach the action
unless you create a custom page and include either standard controller or extension. Or if you want
to add the same meta-tag on all pages I run into this limitation. Is there better way to do this?
Generally - no. Roughly speaking if Salesforce doesn't allow you to do something it usually means there's pretty good hint you're doing in it wrong. I realize it sounds like I'm a fanboy but in reality - can you expand your question with concrete example why would you want to do something like that? For example governor limits are evil, annoying etc. - but they force you to write effective code that doesn't strain the database too much.
if you want to do something whenever objects get saved
That's what triggers are for. Ask yourself a question if the "action" you need to make should happen only from web UI or also when performed from API (mass data load, a smartphone application etc).
if you want to add the same meta-tag on all pages
You could maybe pull off similar result by adding a component to the sidebar. It won't cover all cases (like accessing Reports/Dashboards) but it's hard to say more without knowing what you're really after. Then again - custom VF page overrides won't help you when it comes to Reports either.
I wanted to add this as a comment, but was unable to.
Anyways, For the example that you mentioned in the comment, You can add that jQuery plugin in the Home page side bar component and activate the plugin only on those custom objects where you wnat to run this plugin. You might already know that we can deduce which object a record belongs to by looking at the 1st 3 letter of the record Id, using this logic, check if the record belongs to the custom object you want your plugin to act on and run the plugin.
But As eyescream has pointed out adding script in side bar has its own limitations: you cannot use the global variables , side bar components are not loaded on the reports and dashboard tabs etc.
-ಸಮಿರ್

Using the same backbone relational models to work with both pre-loading and ad-hoc loading of data

I have a tree of models and I'd like to have them load from one big JSON request up front and then be able to change them one at a time without saving the whole tree or reloading the whole tree and without making two versions of each model.
The problem I've encountered is if each of the submodels has a keySource they won't upfront load, but without a keySource you can't do an individual load or save.
My content in the upfront load is the entire object tree fully connected (no id lists) because I didn't see a way around this. Is that the problem? Or is what I'm trying to do just not possible without two versions of the models that are somehow connected?
It is possible to do selective saving if you override the save method of Backbone.Model. I wrote an article on this topic. Your choice if you want to create little sub-models that represent parts of your model. When those are changed, you can get their changedAttributes hash and pass it to the save of the main model. With the method I discuss in the article it is entirely possible to post only parts of your model during a save.
Have you considered using a collection for this? You could override the parse method of collection to create your models. Just a thought.

Best practice for storing images in a database?

I'm creating a web application that needs to store various images. A good example would be an event site:
There are events that have Flyers + Photos (belonging to an event) and Locations that have also photos (belonging to a location).
But I have some troubles creating an ideal solution for all this, because I want to be very flexible. So Photos should be available in multiple resolutions, Flyers could have a back side and thumbnails as well.
Currently I just store the path to the original image in the database and "calculate" the other paths with adding "_small" or "_800x600" to the file name. Although with this approach I have to clean up all the thumbnails when changing a flyer, because I don't keep track of the thumbnails.
So what is the best practice for this? Should I store the paths for the thumbnails too? Are there any famous examples on how to do this? It seems like a rather common problem.
Thanks in advance.

Resources