Giter Club home page Giter Club logo

cloudinary_sfcc_pagedesigner's Introduction

Cloudinary

Cloudinary is a cloud service that offers a solution to any application's entire media management pipeline.

Easily upload images and videos to the cloud. Automatically perform smart media resizing, cropping and conversion without installing any complex software. Collaborate with Marketing and other teams on the same physical asset that gets displayed on your website or the app, so there are no mistakes due to copying or emailing content around. Media is seamlessly delivered through a fast CDN, and much, much more.

Cloudinary offers image and video components for the Salesforce B2C Commerce Page Designer. Using these components and an accompanying Cloudinary account, you can add images and videos to your website pages with the click of a mouse. Common operations such as changing image and video sizes, adding overlays, adapting to mobile devices are easily done through the cartridge using Cloudinary’s AI-based media transformation capabilities. Videos are automatically transcoded to work on all popular browsers and mobile devices, and images are automatically converted to the optimal format. Cloudinary will optimize images and videos to deliver the best quality with the least amount of bandwidth and time consumed, for a great user experience. Our comprehensive APIs and administration capabilities make it easy to extend the cartridge functionality.

Setup

Installing the Cloudinary Page Designer Cartridge

Install the Cloudinary Page Designer cartridges into your Salesforce Commerce Cloud/Demandware Sandbox:

  • Clone this repository.
  • There are two projects representing two cartridges: int_cloudinary_pd and bm_cloudinary_pd
  • Import the two projects into Eclipse as cartridges as described in this Salesforce documentation.
  • Verify that these two cartridges are deployed on your Commerce Cloud sandbox.

Get your Cloudinary account information

If you don’t have a Cloudinary account, sign up for a free account so you can try out image and video transformations and seamless delivery through CDN.

Get your Cloud Name, API Key and API Secret from your Cloudinary account as described here.

Configuring the cartridges

Import metadata

  • The metadata is available in your local git project after you clone the repo.
  • In the Commerce Cloud Business Manager, navigate to Administration > Site Development > Site Import & Export.
  • Upload and import import.zip from the metadata folder.

Update the Business Manager cartridge path

  • Navigate To Administration > Sites > Manage Sites.
  • Select the Business Manager site.
  • Add bm_cloudinary_pd to the cartridge path.

Update the site cartridge path

  • Navigate to Administration > Sites > Manage Sites.
  • Select the storefront site for which you want to enable the components and navigate to the Settings tab.
  • Add int_cloudinary_pd to the cartridge path.

Update site preferences

  • Navigate to Merchant Tools > Site Preferences > Custom Preferences
  • Select CloudinaryPageDesigner and set these values and save.
    • Cloudinary Cloud Name. Provide your Cloudinary cloud name from your Cloudinary account.
    • Cloudinary CNAME. If a special cname was set up from your Cloudinary account, provide it.
    • Cloudinary Api Key. Provide the api key from your Cloudinary account.
    • Cloudinary Api Secret. Provide the api secret from your Cloudinary account.
    • Any of the other optional settings, as required.

Using the cartridge

Using the Cloudinary Image and Video Components

  • In the Page Designer, browse the available components, select the Cloudinary Image or Cloudinary Video component and drag it onto the page.
  • Open up the configuration panel for the component.
    • Choose the image or video you want to use from the embedded Cloudinary media library.
    • Select any presentation options you want to use.
    • Select image or text overlays from the Advanced Configuration options.
    • For videos, customize the video player from the Advanced Configuration options.
  • Save the settings and preview the page.

Additional resources

Additional resources are available at:

Support

You can open an issue through GitHub.

Contact us https://cloudinary.com/contact.

Stay tuned for updates, tips and tutorials: Blog, Twitter, Facebook.

Join the Community

Impact the product, hear updates, test drive new features and more! Join here.

License

Released under the MIT license.

cloudinary_sfcc_pagedesigner's People

Contributors

asad-rafter avatar asisayag2 avatar bruckercloud avatar carlevison avatar dependabot[bot] avatar miskonception avatar naveenpras avatar yaniv-cld avatar yaniv-li avatar yuval-cloudinary avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cloudinary_sfcc_pagedesigner's Issues

Responsive breakpoints get deleted when changes are made to the form.

Steps:

  1. Select an image from the popup.
  2. Notice that the breakpoints for the image are correctly pulled from the api. I use a debugging breakpoint at line 62 of Brpoints.js for this.
  3. Refresh your storefront page
  4. Notice that the breakpoints have been correctly sent to the user.
  5. Add a transformation to "Transformation override"
  6. Save the asset.
  7. Refresh your storefront page.
  8. Notice that the breakpoints have been removed from the asset.
  9. Open the image in the popup, hit insert, save, and the breakpoints will be back on the page.

Named and custom transformation choices aren't remembers when I edit an image.

  1. edit an asset
  2. add a image to an asset
  3. select "transform" and select some transformations
  4. save the change
  5. edit the image again
  6. select "transform"
  7. Notice that your transformations are missing.

The same goes for named transformations.
If I pick a named transformation and then go back and edit the image again, the transformation is not selected. There is no other way to view the chosen transformations other than viewing the page source.

Responsive Srcset is only populated when debug code is on the page.

The code below exists in cartridges/int_cloudinary_pd/cartridge/templates/default/experience/components/assets/cloudinaryImage.isml. If I remove this code from the page the srcset isn't correctly populated. Is this on purpose? Should I always include this code in my content assets that use your custom editor?

Also, should that be window.cnamw or window.cname?


<!-- Uncomment this to expose the raw view model for debugging: -->
<script>
  var value = JSON.parse('<isprint value="${JSON.stringify(pdict.viewmodel)}" encoding="jsonvalue"/>');
  window.cldImages = window.cldImages || [];
  window.cldImages.push(value);
  window.cloudName = value.cloudName;
  window.cnamw = value.cname || null;
  console.log(value);
</script>

Checkboxes not showing for Cloudinary Video Component in Firefox Browser

Browser: Firefox Version 90.0 (64-bit)

Steps to produce:

  1. Open Firefox Browser, login to SFCC
  2. Go to PageDesigner
  3. Select Cloudinary Video Component
  4. Notice that the checkboxes are missing under the category Player options

I checked the debugger console and didn't see any useful error message, but I will paste them just in case:

An iframe which has both allow-scripts and allow-same-origin for its sandbox attribute can remove its sandboxing. 4 ViewLdsBusinessManagerScreen-PageDesigner

Failed to execute ‘postMessage’ on ‘DOMWindow’: The target origin provided (‘https://page-designer.cloudinary.com’) does not match the recipient window’s origin (‘https://<sandbox-hostname>’). srcdoc
labels.undefined is not translated i18n.js:16:14

ERROR in sandbox TypeError: value is null Object {  } <prototype>: Object { … }custom-editor.component.ts:381:12

[iFrameSizer][Host page: iFrameResizer2] IFrame has not responded within 5 seconds. Check iFrameResizer.contentWindow.js has been loaded in iFrame. This message can be ignored if everything is working, or you can set the warningTimeout option to a higher value or zero to suppress this warning.

The responsive break points leave a large image that is too small.

In getBreackpoints() from cartridges/int_cloudinary_pd/cartridge/controllers/Brpoints.js the max_width is too small. Can this be configurable?

I was going to extend the file but the use of local functions inside of a controller makes that difficult. My SF Architect suggested I do a server.replace on the route and move the local functions into a helper method.

The order of transformations applied to breakpoints needs to be adjusted.

Right now, the code applies the breakpoint transformation and then the customer specified OR catridge configured transformations.
This works great for such transformations as dpr_auto, q_auto, and f_auto. This doesn't work great if I take a 1900x1200 image and apply "c_scale,g_south,w_1600". If the breakpoint is < 1600w the custom transformation won't take effect.

Instead I would like to apply the transformations in this order:

  1. Customer specified though both the popup
  2. Breakpoint transformation
  3. Cartridge specified transformation

Attached is my quick and dirty edit of 'cartridges/int_cloudinary_pd/cartridge/static/default/js/cloudinaryImages.js'
I pulled the auto updates into a different object and then reordered the concat.

window.addEventListener('load', renderImgs);

function renderImgs() {
    console.log('render images');
    let conf = {
        cloud_name: window.cloudName
    }
    if (window.cname) {
        conf.cname = window.cname
    }
    cld = cloudinary.Cloudinary.new(conf);
    for (var imageConf of cldImages) {
        if (imageConf.id) {
            var trans = JSON.parse(imageConf.transformation);
            var t = trans.map(tr => {
                if (tr.text) {
                    return buildTextOverlay(tr);
                } else if (tr.publicId) {
                    return buildImageOverlay(tr);
                }
                return tr;
            })
  //*****START
            var autot = [{}];
            if(t[0].dpr){
                autot[0].dpr = t[0].dpr;
                delete t[0].dpr;
            }
            if(t[0].fetchFormat){
                autot[0].fetchFormat = t[0].fetchFormat;
                delete t[0].fetchFormat;
            }
            if(t[0].quality){
                autot[0].quality = t[0].quality;
                delete t[0].quality;
            }
            var url = cld.url(imageConf.publicId, { transformation: t });
            var brs = [];
            var breakpoints = JSON.parse(imageConf.breakpoints);
            if (breakpoints && breakpoints.length > 0) {
                for (let br of breakpoints) {
                    var trs = t.concat([{ crop: 'scale', width: br }]).concat(autot);
                    var s = cld.url(imageConf.publicId, { transformation: trs });
                    brs.push(s + ' ' + br + 'w');
                }
            }
   //========  END
            var img = document.getElementById(imageConf.id);
            if (img) {
                img.src = url;
                img.onerror = onError;
                if (brs.length > 0) {
                    img.srcset = brs.join(',');
                }
            }
        }

    }
}

const onError = (err) => {
    let target = event.currentTarget;
    target.onerror = null;
    target.removeAttribute('srcset');
    target.src = 'https://product-assets-res.cloudinary.com/image/upload/w_250,co_rgb:c23834,e_colorize:100,f_png/PageDesigner/warning.png';
    return true;
}

const buildImageOverlay = (overlay) => {
    let imageOverlay = new cloudinary.Layer().publicId(overlay.publicId);
    return {
        overlay: imageOverlay,
        gravity: overlay.gravity,
        y: overlay.y,
        x: overlay.x,
        opacity: overlay.opacity,
        width: overlay.width,
        flags: 'relative'
    };
};

const buildTextOverlay = (overlay) => {
    if (overlay && overlay.text) {
        let textOverlay = new cloudinary.TextLayer()
            .fontFamily(overlay.fontFamily)
            .fontSize(overlay.fontSize)
            .fontWeight(overlay.bold ? 'bold' : 'normal')
            .fontStyle(overlay.italic ? 'italic' : 'normal')
            .textDecoration(overlay.underline ? 'underline' : 'normal')
            .textAlign(overlay.textAlign)
            .text(encodeURIComponent(overlay.text));
        return {
            overlay: textOverlay,
            gravity: overlay.gravity,
            color: overlay.color,
            y: overlay.y,
            x: overlay.x
        };
    }
};

Removing an image raises an exception

Step to reproduce:

  • add a cloudinary image component to a page
  • select an image and save
  • refresh the page
  • edit the page
  • edit the cloudinary image component
  • remove the image using the trash icon
    An exception is raised in the browser:
ERROR TypeError: Cannot convert undefined or null to object
    at Function.keys (<anonymous>)
    at https://xxxx.sandbox.us01.dx.commercecloud.salesforce.com/on/demandware.static/Sites-Site/-/default/application/page-designer/vendor.7d7c0d7172a76b8f99d0.js:1:1507061

It seems that the exception is rasied when the event sfcc:value is emitted with the payload set to null. Setting the payload to an empty object payload: {} does not raise the exception anymore, and the value for the attribute is not removed but saved as the empty object itself.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.