Panoramio Widget API - Display photos from Panoramio on your own website

With the Panoramio Widget API you can display the photos from Panoramio on your own web site. Geolocated photos from Panoramio are great to enrich your maps or illustrate information where location is an important factor (real estate sites, hotels and vacation sites, routes, trails...).

The Panoramio Widget API is a JavaScript library that provides easy-to-use graphical UI elements and search capabilities so that you can show Panoramio photos on your web site. In addition, we provide ready-made HTML templates that you can embed in a web site using iframe tags so you can take advantage of the Widget API without the need to write any JavaScript.

The Panoramio Widget API is free for both commercial and non-commercial purposes that don't exceed the limit of 100000 queries through the API per day.

JavaScript or iframes: which is right for me?

We provide the Widget API in two flavors: a JavaScript library, and a set of ready-made HTML templates.

With the JavaScript library, you need to link to the JavaScript file in your web site's HTML code, and then write code in JavaScript to create and manipulate widgets.

With the HTML templates, Panoramio provides normal HTML pages that contain just one widget or a combination of them, in fixed configurations; you then add a request for one of these pages into an iframe tag in your own web site so the widget will appear inside your web site, and not in a separate page. You can also look into these HTML templates and use them as examples to understand the JavaScript library.

The following table summarizes the advantages of each flavor.

JavaScript library HTML templates
Ease of deployment Requires some programming Just cut and paste HTML
Required knowledge of programming languages JavaScript, HTML, CSS optional HTML
Flexibility to combine widgets Full power of the Widget API Limited configurations available
User interaction Page behavior is fully customizable Some predefined behaviors available
Interaction between widgets and with rest of the page Fully customizable Generally not possible
Programmatic control over widgets Yes No
UI customization Possible with CSS Size and base color
Hosting web site Must allow JavaScript Must allow iframes

In general, using the JavaScript library directly gives you more flexibility and power, but requires that you write JavaScript code.

Basic concepts

The basic concepts in the Widget API are the request and the widget. A request specifies which photos you want to show, and a widget is a graphical element that shows the selected photos in your browser.

The Widget API provides different types of requests: you can select all photos by a user, all photos that have a certain tag, photos in a predefined set, photos that belong to a particular group, and you can specify an explicit list of photos to show (only in the JavaScript library). In addition, you can restrict some of these requests to only show photos in a specific part of the World.

The Widget API provides two widgets: The photo widget shows one photo at a time. Depending on how you configure it, the user will be able to move to the next and previous photos of a request by pressing the arrows that are shown on the widget; you can also configure the widget so that it advances to the next photo automatically.

The photo list widget shows multiple photos at a time; it can also be configured so that the user can scroll it to see previous and next photos. In both cases, which photos to show, and in which order, is determined by a request.

HTML templates

The Panoramio site provides a set of pages that contain an already-configured widget or a ready-made composition. You can access these pages simply by typing their URL. If you want to use these widgets in your web site, you can use the HTML iframe tag to embed these pages from Panoramio into your web site.

These URLs have the following structure:

http://www.panoramio.com/wapi/template/name.html?option&option&option...

For name you can use:

The options determine what request to use, and the widget's visual appearance. You can give any number of options, separated by the "&" sign.

The following options determine the request. You can use these options with any HTML template, that is, with any value for name.

option meaning
user=12345 Select all photos by the user with id 12345
group=300 Select all photos that are in the group with id 300
tag=sunset Select all photos tagged with the tag "sunset". If you combine the user and tag options, you will get photos by that user that have the given tag.
set=all Select all photos
set=public Select all photos selected for Google Earth
set=recent Select recently-uploaded photos
order=date_desc Show the photos in descending date order, that is, from newest to oldest, instead of the default which is from oldest to newest

You can only use the order option if you use the user and/or the group option. You cannot use the set option together with the user, group, or tag options. If you don't use user, tag, or set, the default is set=public.

The following options determine the visual appearance of your widget. Some options are only valid for some HTML templates. These are all optional, default values will be provided for options that you don't include; however, we recommend that you do not rely on these default values, so that your web site continues to operate unaltered if we change these values.

option valid for meaning
width=400 all Total widget width, in pixels
height=300 all Total widget height, in pixels
bgcolor=%23FF0000 all Background color. You can give a CSS color name, for example bgcolor=red, or a hexadecimal code, for example bgcolor=%23FF0000; note that although the hexadecimal code for red is #FF0000, you need to use %23FF0000 because the # character needs to be escaped when you add it to a URL
columns=4 list How many columns of photos to show in the photo-list widget
rows=1 list How many rows of photos to show in the photo-list widget. Note that you can request more than one row and more than one column to obtain a grid of photos instead of a strip
orientation=vertical list The orientation of the list. Valid values are horizontal and vertical. This controls the position of the arrows, the scrolling direction, and how the photos are sorted. The shape of the list, i.e. whether it is a horizontal or a vertical strip of photos (or a grid) is controlled by the rows and columns options
list_size=6 photo_list How many photos to show in the list
position=bottom photo_list Position of the photo list relative to the single-photo widget. Valid values are left, top, right and bottom
delay=2.5 slideshow Delay, in seconds, before advancing automatically to the next photo

How is this used? Let's say that you want to embed a list of mountain images into your web site. You'd like the list to be 280 pixels wide and 140 pixels high, and contain two rows of four photos. After checking the option tables, you decide that the URL that you need is http://www.panoramio.com/wapi/template/list.html?tag=mountain&width=280&height=140&rows=2&columns=4&orientation=horizontal (this should be all in one line; your browser may be showing the URL split into multiple lines if it doesn't fit the screen). Then, in your web site, you'd add code such as <iframe
style="float: right; margin: 10px"
src="http://www.panoramio.com/wapi/template/list.html?tag=mountain&amp;width=280&amp;height=140&amp;rows=2&amp;columns=4&amp;orientation=horizontal"
frameborder="0" width="280" height="140" scrolling="no" marginwidth="0" marginheight="0"> </iframe>
Again, do not split the URL in multiple lines. Also note that we've replaced the & characters in the URL with &amp; — this is because we are adding them inside a piece of HTML, and they need to be escaped. The style="float..." part indicates how the iframe should appear within your web site; you will need to adapt this to your needs using CSS, or remove that part altogether. We've added exactly that code in this page so you can see the effect — look at the right edge.

Here are other examples that you may want to try:

These widgets have a default behavior for clicks on photos: For the photo, list, and slideshow templates, and for the single-photo widget in the photo_list template, clicking on a photo will open the Panoramio photo page for that photo in another browser window or tab. For the photo-list widget in the photo_list template, clicking on a photo will show that photo in the single-photo widget. Photo widgets show, when the mouse is over them, the photo title and the photographer's name; clicking on them will go to the Panoramio photo page or the Panoramio user page, respectively.

Examples

This section provides several ready-made examples of using Widget API HTML templates that you can cut-and-paste into your web site or blog.

JavaScript API

By accessing the Widget API through the JavaScript library, you get the full functionality of the API. The basic concepts of the JavaScript library are requests and widgets, as with HTML templates. In addition, you may have to use events and photo objects.

Obtaining the JavaScript library

To use the JavaScript Widget API in your web page, you need to load the following URL http://www.panoramio.com/wapi/wapi.js?v=1 to obtain a version localized to the language set in the user's browser configuration, or http://www.panoramio.com/wapi/wapi.js?v=1&hl=de to obtain a version localized to a particular language, German in the example (German's language code is "de"; you can use other language codes). This needs to be loaded in the head section of your page, so your HTML code will end up looking similar to this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
<head>
  <title>My page</title>
  <meta name="description" content="This is my page." />
  <link rel="shortcut icon" type="image/x-icon" href="/img/favicon.ico" />
  <link rel="stylesheet" type="text/css" href="/css/page.css" />
  <script type="text/javascript" src="http://www.panoramio.com/wapi/wapi.js?v=1&amp;hl=fr"></script>
</head>
<body>
  <h1>My page</h1>
  ...

Request

A request is a JavaScript object that specifies which set of photos should be displayed by a widget. You can reuse the same request in multiple widgets. You can specify a request with a JavaScript object literal. To build a request in this way, use code like this in JavaScript:

var myRequest = {
  'tag': 'sunset',
  'rect': {'sw': {'lat': -30, 'lng': 10.5}, 'ne': {'lat': 50.5, 'lng': 30}}
};

These are the valid fields for a request object:

name example value meaning
set panoramio.PhotoSet.ALL Selects one named photo set. Valid values are panoramio.PhotoSet.ALL for all photos, panoramio.PhotoSet.PUBLIC for all photos selected for Google Earth, and panoramio.PhotoSet.RECENT for recently-uploaded photos
tag 'sunset' Selects all photos that have the given tag. The tag must be given between single or double quotes.
user 17 Selects all photos owned by a particular user. The user's id, a number, must be given.
group 300 Selects all photos that are in a particular group. The group's id, a number, must be given.
ids [{'photoId': 1000, 'userId': 187}, {'photoId': 1001, 'userId': 1}, {'photoId': 1003, 'userId': 187}] Selects a particular set of photos. For each photo, you must give its numerical photo id, and the numerical user id of its owner. The photos will be shown in the same order as they are given in this option
rect {'sw': {'lat': -30, 'lng': 10.5}, 'ne': {'lat': 50.5, 'lng': 30}} This option is only valid for requests where you do not use the ids option. It indicates that only photos that are in a certain area are to be shown. The area is given as a latitude-longitude rectangle, with sw at the south-west corner and ne at the north-east corner. Each corner has a lat field for the latitude, in degrees, and a lng field for the longitude, in degrees. Northern latitudes and eastern longitudes are positive, and southern latitudes and western longitudes are negative. Note that the south-west corner may be more "eastern" than the north-east corner if the selected rectangle crosses the 180° meridian
order panoramio.PhotoOrder.DATE_DESC This option is only valid for requests where you use the user option and you do not use the rect option. It requests that photos are shown in a particular order. Valid values are panoramio.PhotoOrder.DATE_DESC, to show them from newest to oldest, and panoramio.PhotoOrder.DATE, to show them from oldest to newest (this is the default)

The ids, user, group, tag, and set options, called "selectors", can be combined with the rect and order options, called "modifiers", only in certain combinations, as listed by this table:

selector no modifier rect order rect and order
ids validinvalidinvalidinvalid
user validvalidvalidinvalid
group validvalidvalidinvalid
user and group validinvalidvalidinvalid
user and tag validinvalidvalidinvalid
tag validvalidinvalidinvalid
set validvalidinvalidinvalid
none validvalidinvalidinvalid
other combinations invalidinvalidinvalidinvalid

If you don't use any selector, the default is 'set': panoramio.PhotoSet.PUBLIC. If you specify invalid options, the Widget API will raise an exception of class panoramio.InvalidPhotoRequestError when you create a widget.

Some requests contain an element of randomness, they may return different results if you run them twice. This can be problematic if you have two or more widgets that are supposed to show the same results, and there is some linkage between the widgets —for example clicking on one photo in a photo thumbnail list displays that photo in a larger format in another widget. To avoid this you can use a panoramio.PhotoRequest object built with a JavaScript constructor. If you pass the same panoramio.PhotoRequest object to two or more widgets, they will share the results of the request and the problem described will not happen. You can create a panoramio.PhotoRequest object in this way by passing it request options, for example with

var myRequest = new panoramio.PhotoRequest({
  'tag': 'sunset',
  'rect': {'sw': {'lat': -30, 'lng': 10.5}, 'ne': {'lat': 50.5, 'lng': 30}}
};

in a similar way to how requests are defined as object literals at the beginning of this section. All widgets that accept requests as object literals also accept requests as panoramio.PhotoRequest objects.

Learn more about requests in the API Reference:

Photo widget

The photo widget shows one photo from a request at a time. You, as the web developer, can instruct it to move to a different photo; depending on how you configure it, the user can also move to another photo by clicking on the arrows.

You create a photo widget by creating a new instance of the panoramio.PhotoWidget class. You need to reserve, in the HTML code of your page, space where the widget will appear. When you create the widget you can specify the request that it should use to show photos, or you can choose to specify this later. You can also give configuration options that will control the widget's appearance and behavior.

You reserve space in your HTML page by adding this code in the appropriate place:

<div id="wapiblock"></div>

You may choose another identifier instead of wapiblock, and you can then combine this with CSS to fine-tune the widget's appearance.

The configuration options for a PhotoWidget are given as a JavaScript object. To build an options object, use code like this in JavaScript:

var myOptions = {
  'width': 300,
  'height': 200
};

These are the valid fields for an options object for a PhotoWidget:

name example value meaning
width 300 Widget width, in pixels
height 200 Widget height, in pixels
croppedPhotos false Whether we should use cropped photos. The value panoramio.Cropping.NO_CROPPING (or false) does not crop the photo. The value panoramio.Cropping.TO_SQUARE (or true) crops the photo to square shape. The value panoramio.Cropping.TO_FILL crops the photo to fill the entire image viewport. Cropped photos may be better when showing lists of small photos for navigation purposes, and normal photos may be better when the full beauty of the photo is needed.

Two additional options, disableDefaultEvents and attributionStyle are discussed later in the Events and Attribution widget sections. Default values are provided for these options, in case you don't use them.

Once you have prepared a request and an options object, and defined a place for the widget in the HTML code, you create a widget with the following JavaScript code:

var widget = new panoramio.PhotoWidget('wapiblock', myRequest, myOptions);
widget.setPosition(0);

If you already have a JavaScript object for the DOM node where the widget should go, you can pass that to the constructor, instead of the node's identifier:

var wapiblock = document.getElementById('wapiblock');
var widget = new panoramio.PhotoWidget(wapiblock, myRequest, myOptions);
widget.setPosition(0);

After the widget is constructed, it will not start showing photos right away: you always need to call the setPosition method at least once. We made this two separate steps so that you have a chance to set up event handlers before the user starts interacting with the widget.

For example, we've added at the beginning of this section, in this web page, the following code:

<div id="div_photo_ex" style="float: right; margin: 10px 15px"></div>
<script type="text/javascript">
  var beaches = {'tag': 'beaches'};
  var photo_ex_options = {'width': 350, 'height': 200};
  var photo_ex_widget = new panoramio.PhotoWidget('div_photo_ex', beaches, photo_ex_options);
  photo_ex_widget.setPosition(0);
</script>

The same effect can be obtained with, for example,

<div id="div_photo_ex" style="float: right; margin: 10px 15px"></div>
<script type="text/javascript">
  var photo_ex_widget = new panoramio.PhotoWidget(
    'div_photo_ex', {'tag': 'beaches'}, {'width': 350, 'height': 200});
  photo_ex_widget.setPosition(0);
</script>

A PhotoWidget exposes the following methods. You can learn more about them in the API Reference:

name usage
enableNextArrow Controls whether the "next" arrow should be visible and active
enablePreviousArrow Controls whether the "previous" arrow should be visible and active
getAtEnd Checks if the widget is at the end of the photo set
getAtStart Checks if the widget is at the start of the photo set
getPhoto Gets information about the currently-displayed photo
getPosition Gets the position of the current photo in the photo set
setPosition Moves to another position in the photo set, and shows that photo
setRequest Defines the request to use to get photos

Learn more about single-photo widgets in the API Reference:

Photo list widget

The photo list widget shows a set of photos from a request at a time. Typically, this widget is used to give an overview of the available photos; a detailed view of a particular photo would be shown using the photo widget. You, as the web developer, can instruct it to move to a different position in the request, to show a different set of photos; depending on how you configure it, the user can also move to another set of photos by clicking on the arrows.

As with the photo widget, you create a photo list widget by creating a new instance of the panoramio.PhotoListWidget class. You need to reserve, in the HTML code of your page, space where the widget will appear. When you create the widget you can specify the request that it should use to show photos, or you can choose to specify this later. You can also give configuration options that will control the widget's appearance and behavior.

You reserve space in your HTML page by adding this code in the appropriate place:

<div id="wapiblock"></div>

You may choose another identifier instead of wapiblock, and you can then combine this with CSS to fine-tune the widget's appearance.

The configuration options for a PhotoListWidget are given as a JavaScript object. To build an options object, use code like this in JavaScript:

var myOptions = {
  'width': 500,
  'height': 100,
  'columns': 5,
  'croppedPhotos': true
};

These are the valid fields for an options object for a PhotoListWidget:

name example value meaning
width 300 Widget width, in pixels
height 200 Widget height, in pixels
croppedPhotos false Whether we should use cropped photos. The value panoramio.Cropping.NO_CROPPING (or false) does not crop the photos. The value panoramio.Cropping.TO_SQUARE (or true) crops the photos to square shape. The value panoramio.Cropping.TO_FILL crops the photo to fill the entire image viewport. Cropped photos may be better when showing lists of small photos for navigation purposes, and normal photos may be better when the full beauty of the photo is needed.
columns 4 How many columns of photos to show in the photo-list widget
rows 1 How many rows of photos to show in the photo-list widget. Note that you can request more than one row and more than one column to obtain a grid of photos instead of a strip
orientation horizontal The orientation of the list. Valid values are panoramio.PhotoListWidgetOptions.Orientation.HORIZONTAL and panoramio.PhotoListWidgetOptions.Orientation.VERTICAL. This controls the position of the arrows, the scrolling direction, and how the photos are sorted. The shape of the list, i.e. whether it is a horizontal or a vertical strip of photos (or a grid) is controlled by the rows and columns options

Two additional options, disableDefaultEvents and attributionStyle are discussed later in the Events and Attribution widget sections. Default values are provided for these options, in case you don't use them.

Once you have prepared a request and an options object, and defined a place for the widget in the HTML code, you create a widget with the following JavaScript code:

var widget = new panoramio.PhotoListWidget('wapiblock', myRequest, myOptions);
widget.setPosition(0);

If you already have a JavaScript object for the DOM node where the widget should go, you can pass that to the constructor, instead of the node's identifier:

var wapiblock = document.getElementById('wapiblock');
var widget = new panoramio.PhotoListWidget(wapiblock, myRequest, myOptions);
widget.setPosition(0);

After the widget is constructed, it will not start showing photos right away: you always need to call the setPosition method at least once. We made this two separate steps so that you have a chance to set up event handlers before the user starts interacting with the widget.

For example, we've added at the beginning of this section, in this web page, the following code:

<div id="div_list_ex" style="float: right; margin: 10px 15px"></div>
<script type="text/javascript">
  var birds = {'tag': 'birds'};
  var list_ex_options = {'width': 400, 'height': 100, 'columns': 5, 'croppedPhotos': true};
  var list_ex_widget = new panoramio.PhotoWidget('div_list_ex', birds, list_ex_options);
  list_ex_widget.setPosition(0);
</script>

A PhotoListWidget exposes the following methods. You can learn more about them in the API Reference:

name usage
enableNextArrow Controls whether the "next" arrow should be visible and active
enablePreviousArrow Controls whether the "previous" arrow should be visible and active
getAtEnd Checks if the widget is at the end of the photo set
getAtStart Checks if the widget is at the start of the photo set
getPhotos Gets information about the currently-displayed photos
getPosition Gets the position of the current photo in the photo set
setPosition Moves to another position in the photo set, and shows that photo
setRequest Defines the request to use to get photos

Learn more about photo-list widgets in the API Reference:

Events

When the user interacts with a web page, the web browser generates browser events. Events are generated when the user clicks or moves the mouse, presses a key, visits a new page, and in many other cases. Different browsers handle browser events in different ways, and making use of these events requires an understanding of the structure of a web page, or, in our case, of the internal structure of the widgets provided by the Widget API. To make it easier for you to manage user interaction, the Widget API detects browser events that are related to it, for example the user clicking on the "next" arrow, and generates synthetic events. These synthetic events carry higher-level information; for example, if a user clicks on a photo in a photo list, the browser may generate an event that says "mouse clicked image so-and-so at pixel 800, 300". The corresponding synthetic event would be "user clicked photo with Panoramio photo id 123, made by user id 300, with title 'View of Mallorca'". The Widget API provides you functions to detect synthetic events and act on them.

The Widget API defines the following types of synthetic events.

symbol meaning
panoramio.events.EventType.PREVIOUS_CLICKED The user clicked on a "previous" arrow.
panoramio.events.EventType.NEXT_CLICKED The user clicked on a "next" arrow.
panoramio.events.EventType.PHOTO_CHANGED The photo or photos shown on a widget have changed —for example because the Widget API has finished loading them.
panoramio.events.EventType.PHOTO_CLICKED The user clicked on a photo.

To detect a synthetic event and act on it, you have to "listen" to it by calling the panoramio.events.listen function. For example, with the following code

var beaches = {'tag': 'beaches'};
var options = {'width': 350, 'height': 200};
var widget = new panoramio.PhotoWidget('wapiblock', beaches, options);
function photoClicked(event) {
  alert('Photo "' + event.getPhoto().getPhotoTitle() + '" was clicked');
}
panoramio.events.listen(widget, panoramio.events.EventType.PHOTO_CLICKED, photoClicked);
widget.setPosition(0);

you create a photo widget, set up event handling so that when the user clicks on a photo on that widget, the function photoClicked will be called.

The function panoramio.events.listen has more options. You can also stop listening to an event type using the functions panoramio.events.unlisten and panoramio.events.unlistenByKey functions. See the API Reference for events for more details.

You'll notice that photoClicked received an argument which we named event. Event handlers always receive such an argument. Its type and value depend on the event that was detected.

event event value
panoramio.events.EventType.PREVIOUS_CLICKED An object with a field named "target" which will be the PhotoWidget or PhotoListWidget object that was clicked.
panoramio.events.EventType.NEXT_CLICKED An object with a field named "target" which will be the PhotoWidget or PhotoListWidget object that was clicked.
panoramio.events.EventType.PHOTO_CHANGED An object with a field named "target" which will be the PhotoWidget or PhotoListWidget object that changed.
panoramio.events.EventType.PHOTO_CLICKED An object of type panoramio.events.PhotoClickedEvent. This object has a method named getPosition that returns the current position in the widget's photo set of the photo that was clicked, and a method named getPhoto that returns a Photo object for the photo that was clicked

The Widget API automatically converts from browser events to synthetic events. In addition, the Widget API defines some default behaviors for certain synthetic events. For example, the default behavior when the "next" photo is clicked is to move to the next photo or photos in the result set, and the default behavior when a photo is clicked is to open the corresponding Panoramio photo page in a new browser window or tab. You can disable some or all of these default behaviors if you don't want them, for example because you want to provide your own behaviors. To do this, you need to use the disableDefaultEvents option in the options object for the PhotoWidget and PhotoListWidget. Its values are

name example value meaning
disableDefaultEvents true Disable all default behaviors
disableDefaultEvents false Keep all default behaviors (this is the default)
disableDefaultEvents [panoramio.events.EventType.PREVIOUS_CLICKED, panoramio.events.EventType.PHOTO_CLICKED] If a list of synthetic event types is provided, the default behaviors for those events will be disabled.

Learn more about events in the API Reference:

Photo object

The Widget API defines a panoramio.Photo class that contains information about a Panoramio photo. If you call, for example, the getPhoto method of a panoramio.PhotoWidget object, or the getPhotos method of a panoramio.PhotoListWidget object, you will get one or more panoramio.Photo objects for the photos that the widgets are currently displaying. Also, if the user clicks on a photo, the Widget API will generate a synthetic event of class panoramio.PhotoClickedEvent, which has a method getPhoto that also returns a panoramio.Photo object.

A Photo object has the following methods. You can learn more about them in the API Reference:

name usage
getPhotoId Returns the Panoramio photo identifier for this photo
getPhotoTitle Returns the title of this photo
getPhotoUrl Returns the URL of the Panoramio photo page for this photo
getPosition Returns the position where the photo was taken, if known
getOwnerId Returns the Panoramio user identifier for the owner of this photo
getOwnerName Returns the name of the owner of this photo
getOwnerUrl Returns the URL of the Panoramio user page for the owner of this photo
getWidth Returns the width of this photo, in pixels, for the full size version (the original), oriented as the photo is to be displayed (i.e. after taking into account EXIF tags that say that the photo should be rotated when displaying it)
getHeight Returns the height of this photo, in pixels, for the full size version (the original), oriented as the photo is to be displayed (i.e. after taking into account EXIF tags that say that the photo should be rotated when displaying it)

Learn more about Photo objects in the API Reference:

Attribution block

The Terms of Service for the Widget API require you to do certain things, such as give proper attribution for the photos. The Widget API tries to help you comply with the Terms of Service by, for example, automatically adding attribution language at the bottom of each widget.

However, there are cases where this default behavior does not make sense; for example if you are using a very narrow widget, the automatic attribution will also be narrow which may be aesthetically unpleasing. Or if you use more than one widget in a visual unit, you may want to display a single attribution block that encompasses the whole group of widgets, instead of having one attribution block for each widget separately. To accommodate these cases, the Widget API gives you some flexibility in how these attribution blocks should be displayed. However, remember that it is still your responsibility to comply with the Terms of Service.

Specifically, we provide two elements of customization:

The attribution style for a widget can be changed by using the option attributionStyle in the widget's options object. This works for both PhotoWidget and PhotoListWidget objects. These are the valid values and their meanings:

name value meaning
attributionStyle panoramio.tos.Style.DEFAULT Show an attribution block at the bottom of this widget, as wide as the widget. The widget's height will be reduced so that the total height, of the widget plus the attribution block, is the one that you indicate in the height field in the widget's options object
attributionStyle panoramio.tos.Style.DEFAULT_ADD Show an attribution block at the bottom of this widget, as wide as the widget. The widget's height will not be modified and will be what you indicate in the height field in the widget's options object, so the total height, of the widget plus the attribution block, will be larger than what you requested
attributionStyle panoramio.tos.Style.HIDDEN Do not show an attribution block for this widget

If you set the attribution style for all your widgets to HIDDEN, you can use the panoramio.TermsOfServiceWidget class to show the attribution block somewhere else in the page, near the widgets, as you are required to do by the Terms of Service. This works in a very similar way to the photo and photo-list widgets. You start by creating a new instance of the panoramio.TermsOfServiceWidget class. You need to reserve, in the HTML code of your page, space where the attribution block will appear. You can also give configuration options that will control the block's appearance and behavior.

You reserve space in your HTML page by adding this code in the appropriate place:

<div id="wapiblock"></div>

You may choose another identifier instead of wapiblock.

The configuration options for a TermsOfServiceWidget are given as a JavaScript object. To build an options object, use code like this in JavaScript:

var myOptions = {
  'width': 300
};

There is only one valid field for an options object for a TermsOfServiceWidget:

name example value meaning
width 400 Widget width, in pixels

Default values are provided for this option, in case you don't use it.

Once you have prepared an options object, and defined a place for the widget in the HTML code, you create an attribution block with the following JavaScript code:

var block = new panoramio.TermsOfServiceWidget('wapiblock', myOptions);

If you already have a JavaScript object for the DOM node where the widget should go, you can pass that to the constructor, instead of the node's identifier:

var wapiblock = document.getElementById('wapiblock');
var block = new panoramio.TermsOfServiceWidget(wapiblock, myOptions);

For example, we've added at the beginning of this section, in this web page, the following code:

<style type="text/css">
  #div_attr_ex {
    position: relative;
    margin: 0 0 20px 30px;
    float: right;
    width: 370px;
  }
  #div_attr_ex_list {
    position: absolute;
    left: 300px;
  }
  #div_attr_ex .panoramio-wapi-images {
    background-color: #E5ECF9;
  }
  #div_attr_ex .pwanoramio-wapi-tos{
    background-color: #E5ECF9 !important;
  }
</style>
<div id="div_attr_ex">
  <div id="div_attr_ex_list"></div>
  <div id="div_attr_ex_photo"></div>
  <div id="div_attr_ex_attr"></div>
</div>
<script type="text/javascript">
  var sand = {'tag': 'sand'};
  var sandRequest = new panoramio.PhotoRequest(sand);
  var attr_ex_photo_options = {
    'width': 300,
    'height': 300,
    'attributionStyle': panoramio.tos.Style.HIDDEN};
  var attr_ex_photo_widget = new panoramio.PhotoWidget(
      'div_attr_ex_photo', sandRequest, attr_ex_photo_options);

  var attr_ex_list_options = {
    'width': 70,
    'height': 300,
    'columns': 1,
    'rows': 4,
    'croppedPhotos': true,
    'disableDefaultEvents': [panoramio.events.EventType.PHOTO_CLICKED],
    'orientation': panoramio.PhotoListWidgetOptions.Orientation.VERTICAL,
    'attributionStyle': panoramio.tos.Style.HIDDEN};
  var attr_ex_list_widget = new panoramio.PhotoListWidget(
    'div_attr_ex_list', sandRequest, attr_ex_list_options);

  var attr_ex_attr_options = {'width': 370};
  var attr_ex_attr_widget = new panoramio.TermsOfServiceWidget(
    'div_attr_ex_attr', attr_ex_attr_options);

  function onListPhotoClicked(event) {
    var position = event.getPosition();
    if (position !== null) attr_ex_photo_widget.setPosition(position);
  }
  panoramio.events.listen(
    attr_ex_list_widget, panoramio.events.EventType.PHOTO_CLICKED,
    function(e) { onListPhotoClicked(e); });
  attr_ex_photo_widget.enablePreviousArrow(false);
  attr_ex_photo_widget.enableNextArrow(false);

  attr_ex_photo_widget.setPosition(0);
  attr_ex_list_widget.setPosition(0);
</script>

A TermsOfServiceWidget exposes the following method. You can learn more about them in the API Reference:

name usage
getHeight Returns the height, in pixels, of the attribution block. You can use this to compute the height needed for your widgets

If you configure the attribution blocks in a way that would violate the Terms of Service, the Widget API will raise an exception of class panoramio.TermsOfServiceViolationError.

Learn more about attribution blocks in the API Reference:

API Reference

The Panoramio Widget API Reference page contains details about all the classes, methods, and constants that have been described here, including the type signatures of all methods. Please refer to that page for any detail on how to use the Widget API.

Attribution Requirements

To use the Panoramio Widget API, you must follow these conditions:

This is just a simplified summary of the conditions. Please check the Panoramio API - Terms of Service for details.

The Widget API tries to help you comply with the Terms of Service by, for example, automatically adding attribution language at the bottom of each widget. However, remember that it is still your responsibility to comply with the Terms of Service; for example, you are not allowed to use CSS or other techniques to hide the Panoramio logo that is inserted by the Widget API at the appropriate places.

Questions

Questions or suggestions? Feel free to contact us at api‌@panoramio.com