Skip to main content
Documentation & User Guides | FotoWare

Optimizely Fotoware add-on (version 5.0) for Optimizely CMS 12 and .net 5

Learn how to install, configure, and use the Optimizely FotoWare add-on

Feature

This article explains how to install, configure, and use the Optimizely FotoWare add-on (version 5.0 or later). 

The export widget will work without Server API License but will then not synchronize metadata, only download the image to Optimizely. 

See 16 Change Log.

Before you start

This article is technical in nature and stipulates knowledge of the Episerver ecosystem. We recommend getting the assistance of someone experienced with Episerver integrations to set up and configure the addon.

Example Image Property and selection dialog from FotoWare

clipboard_ed70c62b16dacf32f318e9976975fa46c.png

Example: TinyMce Toolbox button

clipboard_e6317c2270b46b6cc439ed5a486a5e664.png

How it works

When an asset is selected, the asset is imported into the default Episerver asset management repository and used in an image property (of type ContentReference or Url) or the Rich Text editor. There is also an Episerver scheduled job (to be enabled after installation) which ensures that the imported images and metadata are kept up to date in Episerver if they change in FotoWare.

Key features of the integration:

  1. Easy to add to Episerver solutions, both new and existing solutions.
  2. The integration can be removed without affecting used assets.
  3. Used assets from FotoWare are synchronized into Episerver's default asset management, making it easy for developers familiar with Episerver to get started.
  4. It is possible to configure media to show only local assets, only assets from FotoWare, or both.
  5. A developer can configure their own media models containing the metadata to be synchronized with FotoWare.
  6. Since downloaded media becomes standard Episerver media items, Episerver keeps track of which media is used where in the solution.

Note: Versions 1, 2, and 3 only support imports of static images such as .jpg files. PDFs may work but are not meant to. Video, .svg files, and animated gifs are not currently supported.

Installation

You can find information on Nuget.episerver.com : https://nuget.episerver.com/package/...gIns.Episerver (external link)

Installing and configuring the addon takes less than one hour.

Dependencies

This version of the add-on requires at least EPiServer.CMS.UI 12.
The add-on automatically adds support for Optimizely Commerce and works on version 14 and higher.
Version 3 of EPiServer.CMS.TinyMce is needed for the Toolbox button in editor.

Registering the Selection Widget integration with FotoWare

Before you get started setting up the Episerver integration, you must register the application in the FotoWare Site Configuration: Log in to your FotoWare tenant, open the Tools menu (cogwheel), and choose Site configuration. You find integration settings in the Integrations node, at Applications.

Select Add application to set up the integration for the Selection Widget.

Episerver Widget integration settings.jpg

Type: Choose Web App / API. Then choose API using the radio button below.

Name: Enter the name of the application - for example Episerver integration

Redirect URIs: Here you set the URI that the user should be returned to after authentication is completed. The redirect URI is usually in the form:

http(s)://domain.com/*episerver*/fotoware.plugins.episerver/authentication/callback

Whether or not /episerver is part of the URI depends on how Episerver has been configured. The redirect URI should be set in the Operations Center settings above. Use small caps. In a multi-site scenario, one URI is needed per domain.

User consent: Use markdown syntax to add any custom information that should be displayed when the user uses the plugin for the first time. It's also possible to include a link to a privacy policy.

Access: This is used to control who has access to use the plugin.

Client ID / Client Secret: These values will be auto-generated when you select Save button. See the example below. Copy both values to a temporary location, such as a text file. Later, you must add these to the web.config file of the EpiServer plug-in, in FotoWare:ClientId and FotoWare:ClientSecret value fields. (See web.config section below.)
Once you have done this, you can delete the text file. If you lose the client secret, you can generate a new one and update the web.config file.

 

episerver widget client id and client secret.png

 

Registering the Server-to-Server integration the Operations Center

Next, you will need to register a server-to-server authentication to complete the integration. This can be obtained in the FotoWare Site Configuration: Log in to your FotoWare tenant and open the Tools menu (cogwheel) and choose Site configuration. The integration settings are found in the Integrations node, at Applications.

Add a new application and set the Type to Non-interactive/script, as seen in the screenshot below.

Episerver Server to server integration.jpg

Name the integration and click on Save to generate the Client Id and Client secret values. Copy them to a working document and insert them in the Episerver web.config file in the FotoWare:ServerApi:ClientId and FotoWare:ServerApi:ClientSecret value fields. (See below.)

 

Configuration

1. Startup and appsettings.json:

Add services.AddFotowarePlugin(); into your startup.cs

```
public void ConfigureServices(IServiceCollection services)
{
        //at the end
    services.AddFotowarePlugin(); 
}
```
```
"FotoWare": {
    <!-- all these data is to be obtained from FotoWare -->
    <!-- Documentation ClientId and Secret for Selection widget https://learn.fotoware.com/Integrati..._authorization -->
    "ClientId": "[Enter your Fotoware guid]",
    "ClientSecret": "[Enter your client secret string]",
    
    <!-- Documentation for ServerApi ClientID and Secret https://learn.fotoware.com/Integrati...with_OAuth_2.0 -->
    "ServerApi": {
      "ClientId": "[Enter your Fotoware guid]",
      "ClientSecret": "[Enter your client secret string]"
    },
    <!-- Leave RedirectUri empty or remove if nothing else is told to you. Domain is not required in Episerver multisite solution, 
    example https://domain.com/*episerver*/Fotow...ation/callback  
    or use default /episserver/fotoware.plugins.optimizely/authentication/callback
    where *episerver* is depending on your configuration. CASE SENSITIVE, use LOWER CASE  -->
    "RedirectUri": "/episerver/fotoware.plugins.optimizely/authentication/callback",
    "TenantUrl": "https://my.fotoware.cloud",
    <!-- which asset folder to import images to -->
    "RootFolderId": "[Enter an id to a media folder in Optimizely where you want downloaded assets, for instance 218]",
    
    <!-- presets is used to predefine a width of an image to download, can be used with FotoWare:PreferredDownloadWidth, presets are defined in Fotoware -->
    "PresetUrl": "/fotoweb/me/presets/export/[your presets guid]",
    <!-- these are optional -->
    
    <!-- EnableOnAllImages default is "true" -->
    /*"EnableOnAllImages": "false",*/
    /* ExportWidgetEnableOnAllImages default is "true" */
    /*"ExportWidgetEnableOnAllImages": "false",*/
    /* DisableEpiserverDefaultMediaSelector default is "false" */
    /*"DisableEpiserverDefaultMediaSelector": "true",*/
    "AllowedTypes": ".jpg,.jpeg,.jpe,.gif,.bmp,.png,.gif,.psd",
    /* PreferredDownloadWidth is important to be same or less than the presets width to work, zero is default and will den take the default presets width */
    "PreferredDownloadWidth": "1600",
    /*  Refresh token valid for days, then user need to login again, default is 14 */
    "RefreshToken": {
      "ValidDays": "1"
    }
    /*"ArchiveUrlsToSynchronize": "/fotoware/archives/5000-Archive,/fotoware/archives/5000-Archive-2",*/  }
```

It is also possible to implement and register an instance of the IFotoWareSettings (or extended IFotoWareCommerceSettings) interface to take full control of all settings, for instance, configuring which metadata to synchronize.

2. Configuring additional settings

You need to implement the IFotoWareMedia interface on a content type that inherits from Optimizely ImageData class in your solution. This will enable some additional fields which are used by the add-on to keep the assets in sync with the originals in FotoWare.

```
public class ImageFile : ImageData,  IFotoWareMedia
{ 
    [Editable(false)]
    //Format: pipeseparated values. Example "internal fotoware href|download url|type of download url|site guid"
    public virtual string FotoWareUrl { get; set; } //Links back to Fotoware
    [Editable(false)]
    public virtual DateTime FotoWareModifiedDate { get; set; } //for sync job to work
}
```

 

 

(The FotoWareModifiedDate property is used to keep track of when the asset was last changed in FotoWare. Note: An update to the metadata of an asset in FotoWare only adds 2 seconds to the modified date, therefore we need to keep track of this date and time.)


3. Add to your Tiny MCE configuration toolbar

The button is automatically plugged into Tiny MCE. If it doesn't show up, you probably already have a custom configuration. In startup.cs, add **fotoware-insert-media** to your toolbar.


4. Decorate your Optimizely Property with the FotoWare UIHint attribute: 
 

```
//FotoWareUiHint.FotoWareImage only for ContentReference type
[UIHint(FotoWareUiHint.FotoWareImage)]
public virtual ContentReference ImageAsContentReference { get; set; }
//FotoWareUiHint.FotoWareImageUrl only for Episerver.Url type
[UIHint(FotoWareUiHint.FotoWareImageUrl)]
public virtual Url ImageAsUrl { get; set; }
```

This will replace Optimizely's built-in image editor with an extended editor that supports selecting images from FotoWare as well as local Optimizely images.

To disable the option to select local images in Optimizely, you can add another attribute to your property:

**FotowareConfigurationAttribute** is introduced in version 2. 
`[FotowareConfiguration(DisableDefaultEpiserverMedia = true, ExportWidgetEnabled = WidgetStatus.Disabled, /* only with XhtmlString, will use the export url from fotoware direct, instead of downloading the asset to Optimizely */ UseExportUrlOnly = false, QueryParameters = "crop=false&enhance=false&caption=false&action=false&publication=false&behaviour=false")]`

The attribute should be used in combination with FotoWareUiHint. The parameters are documented here Integrati...gets#section_7.


5. Scheduled jobs  

There are 2 jobs:

  • **FotoWare - Synchronize assets**:  Normally enabled if you want to sync updates from FotoWare to Optimizely. This job will only update assets if the assets have been updated in FotoWare.
  • **FotoWare - Synchronize assets - Force**: As above but will always download the latest image and metadata. Only to be run manually if needed.

![Fotoware_episerve_syncjob.png](/.attachments/Fotoware_episerve_syncjob-a9816ccc-4613-4afb-aebb-17102f7d6ce9.png)


6. Synchronizing metadata from FotoWare to Optimizely


The add-on supports synchronizing metadata between FotoWare and Optimizely through a mapping schema that is defined in your implementation of the **IFotoWareSettings** interface. Implement your own **IFotoWareSettings** and define the mapping schema for metadata that you want to get into the Optimizely assets.
Note: There are a number of default metadata in FotoWare but these can be extended for each client. 

The default mapping schema is set up as follows:


```
MetadataConfiguration = new NameValueCollection
{
    {"5", "Name"},
    {"25", "Keywords"},
    {"80", "Photographers"},
    {"116", "Copyright"},
    {"120", "Description"}
};
```

The mapping schema has keys that match the metadata names in FotoWare and the value is the property name in Optimizely.
Note:  The types need to be the same when changing the configuration, for instance,  Photographers is a list of strings. 

You can find the default keys here: FotoWare_...MP_field_codes

The following example shows how to add custom metadata to the synchronization:


```
MetadataConfiguration = new NameValueCollection
{
    {"5", "Name"},
    {"25", "Keywords"},
    {"80", "Photographers"},
    {"116", "Copyright"},
    {"120", "Description"},
    {"998", "OptimizelyCustomProp"} // set on imagetype
};
```

7. Controlling the structure of downloaded assets in Optimizely [Optional]

Since FotoWare stores assets in a flat list and Optimizely uses a hierarchical structure, assets imported to Optimizely are put in a folder structure. This helps when browsing through the imported assets and it avoids a long list of assets in the same folder which Optimizely does not handle well. It is possible to control how the folder structure for assets in Optimizely is structured. By default, folders are created based on the year and month that the asset was imported into Optimizely, but you can use other structures, for instance, based on metadata in the solution.

This is done by implementing the **IFolderResolver** interface.

8. Customize Tiny MCE html template [Optional]

You can implement your own input HTML when inserting in Tiny Mce, for example, by filling the alt-text or adding some CSS classes. 

This is done by implementing and registering an implementation of **IFotoWareTinyMceTemplateResolver** where you override GetHtml(ContentReference contentReference, string insertingToContentReference=null).


9. Event handling with FotoWare events

Available events are:

  • OnImageDownloading: Raised before downloading an asset with the possibility to cancel the action.
  • OnImageDownloaded: Raised after the asset has been downloaded.
  • OnImageDeleted: Raised in the synchronization job when an asset is deleted or revoked in FotoWare.

 

The following example shows how to register event handlers for these events in an InitializationModule:


```
public void Initialize(InitializationEngine context)
{            
   var events = context.Locate.Advanced.GetInstance<FotoWareEvents>();
   events.OnImageDownloaded += FotoWareHttpClientOnImageDownloaded;
   events.OnImageDownloading += EventsOnOnImageDownloading;
   events.OnImageDeleted += FotoWareHttpClient_FotoWareImageDeleted;
}
```

10. Disabling the FotoWare plugin in Optimizely Commerce Asset list

Implement and register IFotoWareCommerceSettings.PreventCommerceEditorIntegration.

By default, this is enabled.


11. Logging Fotoware.Plugins.Optimizely

The add-on has some logging information that can be used for information and debugging the integration. 

 

12. Extras: code samples

In the nuget package under Tools, you can find some code samples of IFolderResolver, IFotoWareSettings, and IFotoWareTinyMceTemplateResolver implementations as well as additional scheduled jobs for synchronizing entire archives from FotoWare.


13. Troubleshooting

Tip: Turn on Logging Fotoware.Plugins.Optimizely.

 

14. Multisite configuration

From version 3.5 and upwards, you can have different FotoWare instances for different sites in Optimizely.
You must implement the IFotoWareConfig interface. 

Example: For each site

   public class ExampleFotoWareSite1Config : IFotoWareConfig
    {
        public IFotoWareSettings Settings => new ExampleSiteOneFotoWareSettings();//implement a concrete IFotoWareSettings with all settings
        public Guid SiteId => new Guid("b1c98de6-afbd-433c-bbde-97f873edbb12");//Get this guid from Episerver / admin / config / websites
    }

It will fallback to the default IFotoWareSettings set globally if siteid is not found.

 

15. Known issues

An error occurred when sending the request - This is probably due to the handshake with the endpoint not working. Make sure you use Tls12

Note: The callback URL is case-sensitive. Check your URL. The best practice is to use lower case. 


16. FotoWare Optimizely/Episerver Plugin Change Log 


## 5.0.0.0 - mar 2022 
Compatibility with .net 5 and Optimizely CMS 12 and Commerce 14
[Breaking change] From now on the package name is Fotoware.Plugins.Optimizely (just change namespace everywhere)

## 3.6.0.1 - jan 2022
#4734 [BUG] using widget import not working without export widget enabled

## 3.6.0.0 - may 2021 
#3799 Use Export Url direct in WYSIWYG, without downloading the asset in Episerver

## 3.5.0.0 - apr 2021 
#3632 Multisite configuration - you can now have different FotoWare instances per site in Episerver
#2985 FotoWare login token expiry (default 14 days)

## 3.0.0.1 - mar 2021 
#3634 [BUG] Cookie is set as httpOnly from web.config <httpCookies httpOnlyCookies="true" requireSSL="true" />, javascript cant read, popup opens and closes several times

## 3.0.0.0 - jan 2021 
[Breaking] FotoWare:ApiToken in appsetting is now removed and replaced with FotoWare:ServerApi:ClientId and FotoWare:ServerApi:ClientSecret.
#1749 Use Oauth server to server API authentication
#2926 You can now run the plugin with Export Widget without Server API License, then the asset is transferred but not the metadata. 

## 2.2.0.0 - nov 06, 2020 (not public)
Last version with FotoWare:ApiToken configuration. Version 3 introduces Oauth server to server authentication
#392 [BUG] Image property is not updated in Episerver. Change the window dialog popup against Episerver javascript modal window. 
#2967 [BUG] Server error not showing if custom errorpage is enabled on server

## 2.1.0.0 - june 07, 2020
#1800 [BUG] Images like PSD, are saved with psd in name, but should save as export format (jpg)
#1905 [Bug] Tinymce is always opening ExportWidget disregarding config
#1904 [BUG] TemplateResolver for TinyMce is not triggered

## 2.0.4.0 - may 15, 2020
#1747 Accesstoken not fetched caused loop
#1748 Images with åäö not working
#844 cookie login user specific

## 2.0.0.0 - jan 10, 2020
#391 Support for Export Widget
New - FotowareConfigurationAttribute

## 1.3.0.2 - 2019-10-17
#388 Better logging and errormessages

## 1.3.0.0 - 2019-10-07

BUGS
#306 [Bug] Reloading existing synced images didn't allow publish
#307 [Bug] Drag n drop from windows didnt work on FotowareThumbnailSelector
 
NEW FEATURES
#136 Enable FotoWare integration on all UIHint Image settings by default (config)
#137 Change download procedure to always download the latest assets if changed

## 1.0.2.0 - 2019-09-18
#278 [BUG] Enable Custom Domains. Pagescripts validating domain against fotoweb.cloud, this is removed

##inital release 1.0.1.0 - 2019-06-01

 

  • Was this article helpful?