Generate TYPO3 cropVariants for images from CLI - typo3

Is there a way to trigger the generation or update of cropVariants for existing image relations?
My use case: I want to make sure that images always obey a certain aspect ratio. Thus, I have defined a cropVariant called "myCropVariant" for images, for example in pages and some custom tables. This basically works fine, I see a new wizard in the "create image relation" dialog where I can select the cropArea, and even if I don't click on that wizard, the cropVariant image along with the cropVariant database record is created as soon as I save the parent record, using the center of the image as the crop area. Frontend output also works fine using
<f:image cropVariant="myCropVariant"/>
The problem is: I imported a lot of content from another website into the database (using a custom migration CLI command). That also includes images; I've created the corresponding sys_file records and references. The images are rendered fine in frontend, but the cropVariant is not being used. That's because it doesn't exist in database because nobody has clicked through the imported content in backend. Now creating them through the migration script from outside TYPO3 would in theory be possible, but would be pretty nasty (because one needs to know the image dimensions and so on), so I look for a best practice for this through TYPO3 by CLI or something similar.

// get crop variant conf directly from TCA
$cropVariants = $GLOBALS['TCA']['tx_myext_domain_model_example']['columns']['attachments']['config']['overrideChildTca']['types'][2]['columnsOverrides']['crop']['config']['cropVariants'];
// extend for default cropArea configuration
foreach ($cropVariants as &$variant) {
$variant['cropArea'] = ['x' => 0.0, 'y' => 0.0, 'width' => 1.0, 'height' => 1.0];
}
// init variants
$cropVariantCollection = CropVariantCollection::create('', $cropVariants);
// apply configuration to TYPO3\CMS\Core\Resource\File
$processedCollection = $cropVariantCollection->applyRatioRestrictionToSelectedCropArea($file);
// get json string from variants ({"desktop":{"cropArea":{"x":0,"y":0.125,"width":1,"height":0.75},"selectedRatio":"16:9","focusArea":null}})
$cropValue = (string)$processedCollection;
// save e.g. via dataHandler to sys_file_reference

Related

TYPO3 Mask and background image

I have used TYPO3 Mask to make an element with a background image. But it looks like that the image is not saved. It is not shown in the frontend.
Although you use mask you need to define your own rendering. And that depends on the fields you used in the mask definition (using existing fields and creating new fields).
And the names may change when you exported the mask definition.
And you need to create the additional fields in the database (clear cache and do a database compare, or deactive/reactive the extension).
Then you can look for the field with a <f:debug title="inside my CE">{_all}</f:debug> in the rendering template.

TYPO3 Mask_Export: Any way I can export my mask elements without deleting the content?

I'm currently working on a TYPO3 Project and used the mask extension for the first time. I created a lot of elements, used them on the site and filled them with content. I just read in the manual that the mask extension itself causes some performance problems which i didn't knew about..
I installed the mask_export extension to prevent those, but now my content is gone.. I tried to just tell my TYPO3 to use the new content element but my contents ist still not displayed in it.
Is there any way I can use the mask_export extension in a running project without deleting my content?
If You use ext:mask_export your defined mask elements are exported in a new extension.
While the elements are exported they were renamed acording to the new extension name.
If you now deactivate mask and enable your new extension, your existing content (tt_content-records) have the wrong CType (there is no rendering definition).
Solution:
Reenable mask, deactivate your new extension and build a test-page with all content elements, then disable mask and enable your extension and build all content elments again (additionally). Now you can do a SQL-query (SELECT CType FROM tt_content WHERE pid=123) to identify the used CTypes and do database wide replacements.
Be aware, that the extension name may be used in other places (e.g. prefix for tables or fields). This needs to be fixed too.
Conclusion:
It's a bad idea to replace mask after content is inserted, as it generates a lot of manual work in the database.

Adobe CQ5.5-How to display Page Thumbnail using API

I have configured image for my page using sidekick >Page properties>Images tab. Now I want to fetch my this page image(thumbnail) in one of my jsp. Can someone give me pointers or code snippet for api class and method that I can use to achieve this.
Thanks,
Rajeev
I would suggest using the default image component as an example - /libs/foundation/components/image.
If you're putting your code into a component for your specific page type though, your code should be something like this:
if (currentNode.hasNode("image")) {
String imagePath = currentNode.getNode("image").getPath();
Resource imageRes = resourceResolver.getResource(imagePath);
image = new Image(imageRes);
image.loadStyleData(currentStyle);
image.setSelector(".img");
if (!currentDesign.equals(resourceDesign)) {
image.setSuffix(currentDesign.getId());
}
image.draw(out);
}
Keep in mind though, even though you set an image, it does NOT mean it will show up - if you're using the default page dialog for page properties, it will only show a broken image. That's because there is a bug in CQ where the sling:resourceType property of the image doesn't get set, and thus it won't show up. This is because the .img selector that gets put on the image doesn't know what to do, unless it get's pointed to a resource type with a definition for the .img selector, so it can properly render the image.
I've uploaded a package that you can use as a hotfix for the issue with the default /libs/foundation/components/page component dialog, so that it will actually set the resource type when you upload an image. You can find/download the package from my Google Drive
Hopefully that helps. Let me know if you need more help.
EDIT
If you're trying to get the page properties image from one page on another page, you just need to use a resource resolver. You should have one available to you in CQ, so this would essentially be the code:
Resource imageRes = resourceResolver.getResource(pathFromYourDialog);
Image image = new Image(imageRes);
The rest would be the same - you're just giving it a different path to start from.
I think Nicholaus was more on point with his EDIT answer to your immediate need. If the user is providing you a path to the thumbnail via the dialog (i.e. a DAM image).
You can simply create the image, or if it has DAM information you can load it as a DAM Asset and pull the necessary information.
Image image = new Image();
Resource imageResource = resourceResolver.getResource(imageUrl);
Asset imageAsset = imageResource.adaptTo(Asset.class);
Map<String, Object> valueMap = imageAsset.getMetadata();
long width = Long.parseLong(valueMap.get("tiff:ImageWidth").toString());
long height = Long.parseLong(valueMap.get("tiff:ImageLength").toString());
Object titleObject = valueMap.get("tiff:ImageTitle");
String title = (titleObject == null) ? null : titleObject.toString();
if (title != null)
{
image.setTitle(title);
}
image.setWidth(width);
image.setHeight(height);
image.setUrl(imageUrl);
This is a little long hand for what Nicholaus had suggested, the Image class will create itself based off the Resource you pass it. (actually upvoted Nicholaus for that, have some optimizations we can make).
Another, simpler option would be to just use the src that the user passes through, in the event that all you're doing is setting a thumbnail. I'm guessing you could be safe in doing something like:
in java:
String thumbSrc = properties.get("thumbSrc", "defaultThumbnail.path");
if (!thumbSrc.isEmpty())
{
pageContext("thumbSrc", thumbSrc);
}
in jsp:
<img alt="thumbnail" src="${thumbSrc}"/>
or if you don't want to do anything in the java you could just do something like
<c:if test="${not empty properties.thumbSrc}">
<img alt="thumbnail" src="${properties.thumbSrc}"/>
</c:if>
In order to get the same result as the first part in just jsp, you'd need to wrap it in a choose, because passing it through some processing before sending to view makes it easier to set default values.

Zend Framework Dynamically added fields of a form and populate

I have been attempting to create a form where a user can simply press a button and the form will add a new field for the user to use. I have 2 of these dynamically added field types.
Firstly a field where a user can upload files, by pressing the add button another field is pasted underneath the current field and is ready for use.
I have followed an old guide on how to get this done with a bit of ajax and jQuery.
This guide to be exact: http://www.jeremykendall.net/2009/01/19/dynamically-adding-elements-to-zend-form/
As you can see it's from 2009 and a bit outdated yet it still works under the current Zend Framework version 1.11.11
The problem however arises now that i want an edit / update version of the form. I need to populate it's fields but first of all i need to create enough fields for the data to be stored in. So when there's 3 files that have been uploaded it should create 2 additional fields and place the 3 file names in these fields ready to be edited and updated. Simply using $form->populate($stuff) is not going to work
I just have no idea how to accomplish this and the tutorial on dynamically added fields only goes as far as the addAction and not how to create the editAction under these conditions.
Is there any tutorial out there on how to create and manage forms such as these? I'm sure i am not the only one who's had the idea to builds these kind of forms?
I can add my code if there's a request for it but it's the same as the example from the guide, just a different set of elements in the form.
Adding a small example of it's use.
A user adds an item with 3 files, these files are uploaded along with a filename so in the database it appears like this : File_Id : '1' , File_Name : 'SomeFile' , File_location : 'somewhere/on/my/pc/SomeFile.txt'.
Now the user realizes he forgot a file or wants to delete a file from that list, he goes to the edit page and here i want the form to display the previously added filenames. So if there's 3 files it shows 3 and when there's 2 it shows 2 etc. How do i build a form to dynamically add fields based on the number of uploaded files and then populate them?
Any advice on how to handle this is well appreciated :)
You can make use of the semi-magic setXxx() methods of the form.
Inside the form:
public function setFiles($files) {
foreach ($files as $file) {
$this->addElement(/* add a file element */);
//do other stuff, like decorators to show the file name, etc.
}
}
In your controller:
$files = $model->getFiles();
$form = new Form_EditFiles(array('files' => $files));
By passing an array with key files you will make the form try to call the method named setFiles(), which you have conveniently provided above.
This should push you in the right direction, or so I hope at least.
If I understand you correctly you want to populate file upload fields, which is not possible because of security reasons.
Edit:
You can add Elements inside of the Controller via $form->addElement() (basicly just like the $this->addElement() statements in the Tutorial)

Raw HTML in body text after importing content using transmorgrifier

I'm using a transmorgrifier recipe to import some data from drupal into a Plone 4.1 based buildout. The buildout is based on https://github.com/claytron/drupal-plone-transmogrifier, (mostly I updated it to use plone 4.1 instead of 4.0). The import works, I successfully imported data from a drupal site into my plone site. The only issue is that the html tags from the imported html show as the literal tags.
If, after the successful import, I manually go to each item and select 'edit' then click 'save' then the html is interpreted properly, but that would be a lot of editing and saving in order to fix my problem.
see screenshot of freshly imported content with html tags showing.
The blueprint doing the actual import of the field is (I believe) the one shown below:
[text_mimetype]
blueprint = collective.transmogrifier.sections.inserter
key = string:_text_mimetype
value = string:text/html
I experimented with using text/structured instead of text/html in the blueprint but that gave the same result:
What I need is either an additional blueprint that causes the html to be interpreted or a hints on how to ensure that my html gets interpreted at import.
The full list of blueprints used in my pipeline are shown here:
https://github.com/claytron/drupal-plone-transmogrifier/blob/master/src/my.migration/my/migration/config/base.cfg
Ran into the same problem when migrating content using wsapi4plone.core.
Solution: Pin zope.contenttype to version 3.5.5 (the default in the upcoming 4.1.1)
Cause: PLIP #9938 - http://dev.plone.org/plone/ticket/9938 as per esteele.
If it works under Plone 4.0 but not under Plone 4.1, then I'm guessing it has to do with the "factor custom output transformations out of the editors" PLIP that was merged as a part of the Plone 4.1. I would look into the changes from that PLIP and see how the pipeline needs to be adjusted.
Actually that section only insert a value "text/html" in the key "_text_mimetype"
The real encapsulation is done here:
[mimetype_encapsulator]
data-key = text
mimetype = python:item.get('_%s_mimetype' % key)
# replace the data in-place
field = key
condition = mimetype
more info: http://pypi.python.org/pypi/plone.app.transmogrifier#mime-encapsulator-section
Anyway i've experimented that it's not strictly mandatory to encapsulate the html text, it works also with a simple string.
Bye, Giacomo