ErHaWeb / klaro_consent_manager

TYPO3 integration of Klaro! Consent Management. Klaro! is a powerful tool that protects the privacy and data of your visitors and helps you run a GDPR compliant website.
Other
1 stars 0 forks source link

Optimize height of placeholder maybe using the preview image and show CE title? #3

Closed hilburger closed 10 months ago

hilburger commented 10 months ago

Hi Eric!

Awesome work - this is one of the most useful extensions of 2023 :-)

My "problem" no.1: I have a little problem trying to avoid skipping of the layout due to the dynamic height of the placeholder, especially with (Youtube-)videos.
You know the phenomenon for sure that as soon as you accept the layout gets into place und that looks pretty disturbing from an UX point of view:

image

looks like this after accepting:

image

My "problem" no.2: Additionally the headline which often/normally contains the title of the video is invisible until accepting Youtube, so there is no information what will be shown and we lack a very important trigger/motivation to click and accept.

Idea for a solution:

  1. Get the CE's title and place it above the video placeholder or check respect the CE's layout settings. I guess the second idea is more complex.
  2. Get the thumbnail from the video which is normally stored locally the first time grabbing the video URL. This would give us the at least the right aspect ratio an be able to use a Bootstrap card overlay wrapping: https://getbootstrap.com/docs/5.3/components/card/ image
  3. Maybe an integrator could add a custom Fluid template to wrap the placeholder which would probably offer most of what is needed for sloving this without getting too deep into coding?

What do you think?

ErHaWeb commented 10 months ago

Thank you for your feedback.

Problem 1: Regarding your problem with the height of the contextual consent box, I am still working on a solution. The difficulty here is that the box is dynamically generated by the default Klaro script and I have no direct control over it. I am thinking about recompiling the Klaro script with the necessary changes to allow templating via fluid.

For now, it may be sufficient to select the Contextual Consent Box using the data-name attribute. For the YouTube service, the necessary (S)CSS for a 16:9 aspect ratio should look something like this:

SCSS

[data-type="placeholder"] {
  &[data-name="youtube"] {
    height: 0;
    padding: 0 0 56.25%;
    position: relative;

    > .cm-as-context-notice {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      height: 100%;
      width: 100%;
    }
  }
}

or simple CSS

data-type=placeholder][data-name=youtube] {
  height: 0;
  padding: 0 0 56.25%;
  position: relative;
}

[data-type=placeholder][data-name=youtube] > .cm-as-context-notice {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  height: 100%;
  width: 100%;
}

Problem 2: Regarding your problem with the headings: In the feature release released today, the heading is kept by default. In addition, it is possible to specify whether headings should also be included in the Contextual Consent Box using the following TypoScript constant:

plugin.tx_klaroconsentmanager.settings.contextualconsent.mainSectionOnly = 1

Values: 0 = All content (except the frame) is enclosed in the Contextual Consent Box. 1 = Only the main content is enclosed in the Contextual Consent Box.

Caution Please note that the Klaro extension extends the default layout of EXT:fluid_styled_content (EXT:fluid_styled_content/Resources/Private/Layouts/Default.html) to make the above distinction. If you have already overridden this layout in your integration, you will need to manually insert the Klaro extension changes there.

--

I hope this info helps you for now.

hilburger commented 10 months ago

Thank you Eric! I have had solved this with a Bootstrap (5) class which basically does just the same like your code:

div[data-type="placeholder"] {
  .klaro.cm-as-context-notice {
    @extend .ratio;
    @extend .ratio-16x9;
    margin-bottom: var(--contentcontainer-gap);
    padding: 0;

    .context-notice {
      border-radius: inherit;
      border: none;

    }
  }
}

I will test the new version with headline handling now! :)

hilburger commented 10 months ago

To the FSC-override to keep the headings: I have an HTML-wrapping problem here.

I am using BS-Package and container and somewhere (I am still looking for the line in the template) the column-wrapping is messed up. Maybe a (not) closing div tag?

image

hilburger commented 10 months ago

Looks like this has to be solved differently when bootstrap_package is installed. Overwriting the default FSC layout does not work without killing the frame feature set there. I am still investigating.

hilburger commented 10 months ago

Looks like this has to be solved differently when bootstrap_package is installed. Overwriting the default FSC layout does not work without killing the frame feature set there. I am still investigating.

Update: The frame handling has been moved to a Viewhelper by Benjamin: https://github.com/benjaminkott/bootstrap_package/blob/master/Classes/ViewHelpers/FrameViewHelper.php

hilburger commented 10 months ago

It works in my bootstrap_package based site package:

<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:bk2k="http://typo3.org/ns/BK2K/BootstrapPackage/ViewHelpers" data-namespace-typo3-fluid="true">
<bk2k:data.imageVariants as="variants" variants="{settings.responsiveimages.variants}" />
<f:variable name="backendlayoutConfig">{settings.responsiveimages.backendlayout.{backendlayout}}</f:variable>
<f:variable name="columnConfig">{backendlayoutConfig.{data.colPos}}</f:variable>
<f:if condition="{columnConfig}">
    <bk2k:data.imageVariants as="variants" variants="{variants}" multiplier="{columnConfig.multiplier}" gutters="{columnConfig.gutters}" corrections="{columnConfig.corrections}" />
</f:if>

<f:if condition="{containerContext}">
    <f:for each="{containerContext}" as="context">
        <f:variable name="containerConfig">{settings.responsiveimages.container.{context.CType}}</f:variable>
        <f:variable name="containerColumnConfig">{containerConfig.{data.colPos}}</f:variable>
        <f:if condition="{containerColumnConfig}">
            <bk2k:data.imageVariants as="variants" variants="{variants}" multiplier="{containerColumnConfig.multiplier}" gutters="{containerColumnConfig.gutters}" corrections="{containerColumnConfig.corrections}" />
        </f:if>
    </f:for>
</f:if>

<f:comment>COOKIE-CONSENT KLARO EXT</f:comment>
<f:if condition="{contextualconsentService}">
    <f:variable name="attributes" value=' data-name="{contextualconsentService.0.data.name}"'/>
    <f:if condition="{settings.contextualconsent.replaceAttributes}">
        <f:variable name="attributes" value='{attributes} data-replace="{settings.contextualconsent.replaceAttributes}"'/>
    </f:if>
</f:if>

<bk2k:frame
    id="c{data.uid}"
    type="{data.CType}"
    size="default"
    layout="{data.frame_layout}"
    frameClass="{data.frame_class}"
    frameAttributes="{frameAttributes}"
    spaceBefore="{data.space_before_class}"
    spaceAfter="{data.space_after_class}"
    options="{data.frame_options}"
    variants="{variants}"
    backgroundColor="{data.background_color_class}"
    backgroundImage="{backgroundImage.0}"
    backgroundImageOptions="{data.background_image_options}"
>
    <f:if condition="{data._LOCALIZED_UID}"><a id="c{data._LOCALIZED_UID}"></a></f:if>
        <f:if condition="{contextualconsentService} && {settings.contextualconsent.mainSectionOnly} == '0'"><f:format.raw value='<div{attributes}>'/></f:if>
    <f:render section="Before" optional="true"><f:render partial="DropIn/Before/All" arguments="{_all}" /></f:render>
    <f:render section="Header" optional="true"><f:render partial="Header/All" arguments="{_all}" /></f:render>
        <f:if condition="{contextualconsentService} && {settings.contextualconsent.mainSectionOnly} == '1'"><f:format.raw value='<div{attributes}>'/></f:if>
    <f:render section="Main"   optional="true" />
        <f:if condition="{contextualconsentService} && {settings.contextualconsent.mainSectionOnly} == '1'"><f:format.raw value='</div>'/></f:if>
    <f:render section="Footer" optional="true"><f:render partial="Footer/All" arguments="{_all}" /></f:render>
    <f:render section="After"  optional="true"><f:render partial="DropIn/After/All" arguments="{_all}" /></f:render>
        <f:if condition="{contextualconsentService} && {settings.contextualconsent.mainSectionOnly} == '0'"><f:format.raw value='</div>'/></f:if>
</bk2k:frame>
</html>
hilburger commented 10 months ago

Tomorrow or the day after tomorrow I will try to wrap the Text-Media-CE of the BS-Package.

It has to be done directly within it's Fluid templates. For example in vendor/bk2k/bootstrap-package/Resources/Private/Templates/ContentElements/TextmediaAbove.html and the other layouts of Text-Media-CE (within one's site package of course ;) ) and the SCSS/HTML needs to be changed a bit.

But then it does not matter which one you use in the backend Textmedia oder External Media CE.

I change the consent lines to:

<f:if condition="{contextualconsentService} && {settings.contextualconsent.mainSectionOnly} == '1' && {data.CType} != 'textmedia'">
  <f:format.raw value='<div{attributes}>'/>
</f:if>

<f:render section="Main"   optional="true" />

<f:if condition="{contextualconsentService} && {settings.contextualconsent.mainSectionOnly} == '1' && {data.CType} != 'textmedia'">
  <f:format.raw value='</div>'/>
</f:if>
ErHaWeb commented 10 months ago

Please note that so far I am only considering content output based on Fluid Styled Content by default. The Bootstrap Package uses a different method. Accordingly, the Klaro addition must also be done differently there. In the end, it is up to the integrator to make sure that the Klaro additions are inserted at the right place in the content rendering process. Even if I consider the default case, I am not able to cover every conceivable case.

Below I describe all the required information:

Required addition in the DataProcessing of the FLUIDTEMPLATE of the content rendering:

dataProcessing.100 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
dataProcessing.100 {
    if.isTrue.field = tx_klaroconsentmanager_service
    table = tx_klaroconsentmanager_service
    uidInList.field = tx_klaroconsentmanager_service
    pidInList = 0
    as = contextualconsentService
}

Inside the Fluid Template: All subsequent specifications should be made within the content frame in order to be able to represent margins, for example, regardless of contextual consents.

Variable assignment at the beginning

<f:if condition="{contextualconsentService}">
    <f:variable name="attributes" value=' data-name="{contextualconsentService.0.data.name}"'/>
    <f:if condition="{settings.contextualconsent.replaceAttributes}">
        <f:variable name="attributes" value='{attributes} data-replace="{settings.contextualconsent.replaceAttributes}"'/>
    </f:if>
</f:if>

Specification before header and main content:

<f:if condition="{contextualconsentService} && {settings.contextualconsent.mainSectionOnly} == '0'">
    <f:format.raw value='<div{attributes}>'/>
</f:if>

Specification after header and before main content:

<f:if condition="{contextualconsentService} && {settings.contextualconsent.mainSectionOnly} == '1'">
    <f:format.raw value='<div{attributes}>'/>
</f:if>

Specify directly after main content:

<f:if condition="{contextualconsentService} && {settings.contextualconsent.mainSectionOnly} == '1'">
    <f:format.raw value='</div>'/>
</f:if>

Specification after all other specifications:

<f:if condition="{contextualconsentService} && {settings.contextualconsent.mainSectionOnly} == '0'">
    <f:format.raw value='</div>'/>
</f:if>

-- Regarding your code

I still don't understand why you added {data.CType} != 'textmedia' but otherwise your customizations look fine so far.

hilburger commented 10 months ago

Thank you for your detailed feedback! My idea is to follow Georg's approach from his news and add a simple example for the bootstrap_package for videos. I am testing this and would hand it to be added in the docs.

Regarding my code

The CType textmedia is introduced by Benjamin within the package and uses differently structured Fluid template than External Media. Or vice-versa :)

The default Fluid template of Textmedia CE looks like this (example from Resources/Private/Templates/ContentElements/TextmediaBelow.html):

<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:layout name="Default" />
<f:section name="Header" />
<f:section name="Main">
    <div class="textmedia textmedia-below">

        <div class="textmedia-item textmedia-gallery">
            <f:render partial="Media/Gallery" arguments="{_all}" />
        </div>

        <div class="textmedia-item textmedia-text">
            <f:render partial="Header/All" arguments="{_all}" />
            <f:format.html>{data.bodytext}</f:format.html>
        </div>
    </div>

</f:section>
</html>

Taking care of this structure one needs to exclude the wrapping Klaro code from wrapping (in the Layouts/Default.html)

<f:render section="Main" optional="true" />

to preserve the headline(s). It looks like it has to wrap this part within the Textmedia-Fluid:

<div class="textmedia-item textmedia-gallery">
  <f:render partial="Media/Gallery" arguments="{_all}" />
</div>

I hope this makes sense. :-D

ErHaWeb commented 10 months ago

Thanks to you for the preliminary work. Once I get around to writing the full documentation, I'll go over your steps in the bootstrap package again practically and include your findings in the documentation.

Regarding your code:

Ok, now I understand. The template TextmediaBelow.html empties the section "Header" and writes the header in the context of the "Main" section. In this case, the Contextual Consent wrapper must actually reside in the single template and can no longer reside globally in the layout.

Here it should be noted again that these problems only exist for the use case where the header is to be excluded from Contextual Consent. Otherwise, it would even be feasible outside of Fluid with bare TypoScript under tt_content.stdWrap.outerWrap as it originally was (the newer replaceAttributes still to add). The solution in the parent TypoScript would probably be more compatible with the various forms of output but would not have the flexibility needed to exclude the header.

For this reason, it is probably a help to keep the different integration cases in the documentation. I think trying to automatically check and apply the appropriate override would go too far and be too error-prone.

hilburger commented 10 months ago

Great, this is exactly how I thought about it. Such integration over the standard should be left to the specific cases to integrators. If we can help them via examples within the docs it the most efficient and flexible way to go.

Thanks again for all your efforts, great extension!

hilburger commented 10 months ago

PS. I would take care of finishing my bootstrap_package integration and place a compact documentation of my steps here. I will check if it is enough to adopt

vendor/bk2k/bootstrap-package/Resources/Private/Partials/ContentElements/Media/Gallery.html and vendor/bk2k/bootstrap-package/Resources/Private/Partials/ContentElements/Media/Type.html

The good thing is that I'd say the integration for video (maybe also audio like Soundcloud) content elements in the bootstrap_package is probably the only general case most people need. So changes here are not too overwhelming.