> ## Documentation Index
> Fetch the complete documentation index at: https://dokumentation.websale.de/llms.txt
> Use this file to discover all available pages before exploring further.

# Download template: tags

> The tags of the download template: error message, download ID input, list of orders, and list of download files.

If a shop sells download products, the buyer receives a download ID after the order. With it, they call up a separate page on which their files are available for download. This page is the download template.

The template contains **four sections**, of which the shop only ever displays one. Which one it is depends on the request: with a valid download ID, without an ID, after logging in to the shop, or after an error.

Guide: Offering download products

| Section | Displayed |
| - | - |
| `DownloadError` | if a download was not possible |
| `DownlIdInput` | if the request was made without a download ID |
| `OrderList` | if a logged-in buyer calls up their orders with download products |
| `ArticleList` | if the files of an order are displayed |

> [!WARNING]
>
> The tags of this template have no prefix. `Msg`, `OrderNumber` or `File` are named exactly like that and only apply here. They have nothing to do with tags of the same name in other templates.

> [!NOTE]
>
> Each section is bracketed as a range. Anything outside all four ranges, for example the header and footer, always appears.

## The structure of the template

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{DownloadError}
   <!-- Ein Download war nicht möglich -->
{/DownloadError}

{DownlIdInput}
   <!-- Der Käufer soll seine Download-ID eingeben -->
{/DownlIdInput}

{OrderList}
   <!-- Die Bestellungen des angemeldeten Käufers -->
{/OrderList}

{ArticleList}
   <!-- Die Dateien einer Bestellung -->
{/ArticleList}
```

## DownloadError: the error case

This section appears if a requested download was not delivered, for example because the number of permitted downloads has been used up or the period has expired.

| Tag | Returns |
| - | - |
| `DownloadID` | the download ID |
| `PrdName` | the name of the product |
| `ErrMsg` | the error message |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{DownloadError}
   <h1>Download nicht möglich</h1>
   <p>~ErrMsg~</p>
   <p>Betroffenes Produkt: ~PrdName~ (Download-ID ~DownloadID~)</p>
{/DownloadError}
```

> [!NOTE]
>
> The text in `ErrMsg` comes from the error messages of the download module. The messages about the exceeded number and the expired period may contain the placeholders `~maxdownloads~` and `~expdt~`. The shop replaces them with the permitted number or the expiry date respectively.

## DownlIdInput: entering the download ID

This section appears if the page was called up without a download ID or the specified ID is incorrect. The buyer then gets an input field.

| Tag | Returns |
| - | - |
| `Msg` | a general notice text |
| `DownloadID` | the most recently entered download ID |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{DownlIdInput}
   <p>~Msg~</p>
   <form method="post">
      <label for="downloadid">Ihre Download-ID</label>
      <input type="text" id="downloadid" name="DownloadId" value="~DownloadID~">
      <button type="submit">Weiter</button>
   </form>
{/DownlIdInput}
```

> [!NOTE]
>
> In the error case, `Msg` contains the notice about the invalid ID and is otherwise empty. Your own introductory text therefore belongs directly in the template and not in this tag.

> [!WARNING]
>
> Between two download attempts, the shop deliberately waits one second so that download IDs cannot be guessed by trial and error. Therefore, do not build any automatic retries into the form.

## OrderList: the buyer's orders

This section appears if a buyer logged in to the shop calls up their orders with download products.

| Tag | Returns |
| - | - |
| `Msg` | a general notice text |
| `Orders` | the loop over the orders |
| `NoOrders` | applies if there is no order with download products |
| `OrderNumber` | the order number |
| `OrderDateTime` | date and time |
| `ShowArtsUrl` | the address at which the files of this order appear |
| `DownloadAllowed` | applies if at least one file may still be downloaded |
| `DownloadDone` | applies if at least one file has already been downloaded |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{OrderList}
   <p>~Msg~</p>

   {NoOrders}
      <p>Sie haben noch keine Bestellung mit Download-Produkten.</p>
   {/NoOrders}

   <ul>
      {@Orders}
         <li>
            <a href="~ShowArtsUrl~">Bestellung ~OrderNumber~ vom ~OrderDateTime~</a>
            {DownloadAllowed}<span class="offen">Downloads möglich</span>{/DownloadAllowed}
            {DownloadDone}<span class="erledigt">bereits heruntergeladen</span>{/DownloadDone}
         </li>
      {/@Orders}
   </ul>
{/OrderList}
```

> [!WARNING]
>
> `Orders` is a pure loop tag and is opened with `{@Orders}`. A simple bracketing `{Orders}` has no effect. `NoOrders` is there to answer the question of whether there are any orders at all. The previous documentation lists `Orders` as a range tag.

> [!NOTE]
>
> `OrderDateTime` is the point in time at which the download products were added to the download management. This is usually the time of the order, but it does not have to match it to the second.

> [!NOTE]
>
> `DownloadAllowed` and `DownloadDone` are not mutually exclusive. An order with several files can be both at the same time.

## ArticleList: the files of an order

This section shows the download products of an order.

| Tag | Returns |
| - | - |
| `Msg` | a general notice text |
| `OrderNumber` | the order number |
| `DownloadID` | the download ID |
| `Articles` | the loop over the products |
| `PrdName` | the product name |
| `PrdNumber` | the product number |
| `PrdThumbnailURL` | the address of the thumbnail image |
| `File` | the file name |
| `FileSize` | the file size in a suitable unit |
| `DownloadsDone` | the number of downloads already made |
| `Downloads` | the number of permitted downloads |
| `ValidDateTime` | the point in time until which downloading is allowed |
| `DownloadAllowed` | applies if the file may still be downloaded |
| `DownloadUrl` | the address that starts the download |
| `Back` | applies if the request came from `OrderList` |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{ArticleList}
   <p>~Msg~</p>
   <h1>Bestellung ~OrderNumber~</h1>

   <table>
      {@Articles}
         <tr>
            <td>
               {PrdThumbnailURL}<img src="~PrdThumbnailURL~" alt="">{/PrdThumbnailURL}
            </td>
            <td>
               ~PrdName~<br>
               <small>~PrdNumber~</small>
            </td>
            <td>~File~ (~FileSize~)</td>
            <td ~ddwrnclass~>~DownloadsDone~ von ~Downloads~</td>
            <td ~vdwrnclass~>~ValidDateTime~</td>
            <td>
               {DownloadAllowed}
                  <a href="~DownloadUrl~">Herunterladen</a>
               {/DownloadAllowed}
               {!DownloadAllowed}
                  <span>nicht mehr verfügbar</span>
               {/!DownloadAllowed}
            </td>
         </tr>
      {/@Articles}
   </table>

   {Back}
      <a href="javascript:history.back()">Zurück zur Übersicht</a>
   {/Back}
{/ArticleList}
```

> [!WARNING]
>
> `Articles` is also a pure loop tag and is opened with `{@Articles}`. The previous documentation lists it as a range tag.

### What the counters actually output

> [!NOTE]
>
> `Downloads` and `ValidDateTime` do not always output a number or a date. If the number is unlimited, the text for "unlimited" appears there, and the same applies to the period. If the download was stopped, `ValidDateTime` contains the text for "stopped". Therefore, do not calculate with these values in the template.

> [!NOTE]
>
> `FileSize` outputs a hyphen if the file no longer exists on the server. This is the quickest way to detect a missing download product.

> [!NOTE]
>
> `File` only contains the file name without a directory, and `DownloadUrl` is only filled if the download is actually still allowed. Therefore, place the link within `{DownloadAllowed}`.

### Highlighting exhausted and expired downloads

Two further tags return a ready-made CSS class for the warning case.

| Tag | Returns |
| - | - |
| `ddwrnclass` | a `class` attribute if the permitted number has been reached |
| `vdwrnclass` | a `class` attribute if the period has expired |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<td ~ddwrnclass~>~DownloadsDone~ von ~Downloads~</td>
<td ~vdwrnclass~>~ValidDateTime~</td>
```

> [!NOTE]
>
> The tags output the complete attribute, i.e. `class='warning'`, and nothing else. They therefore belong directly in the opening element without their own attribute name. Neither is described in the previous documentation, but both exist in the shop.

## Overview of the tags

| Tag | Section | Single tag | Range tag | Negative range tag | Loop tag |
| - | - | - | - | - | - |
| `DownloadError` | Template | – | yes | yes | – |
| `DownlIdInput` | Template | – | yes | yes | – |
| `OrderList` | Template | – | yes | yes | – |
| `ArticleList` | Template | – | yes | yes | – |
| `DownloadID` | DownloadError, DownlIdInput, ArticleList | yes | – | – | – |
| `PrdName` | DownloadError, ArticleList | yes | – | – | – |
| `ErrMsg` | DownloadError | yes | – | – | – |
| `Msg` | DownlIdInput, OrderList, ArticleList | yes | – | – | – |
| `Orders` | OrderList | – | – | – | yes |
| `NoOrders` | OrderList | – | yes | yes | – |
| `OrderNumber` | OrderList, ArticleList | yes | – | – | – |
| `OrderDateTime` | OrderList, ArticleList | yes | – | – | – |
| `ShowArtsUrl` | OrderList | yes | – | – | – |
| `DownloadAllowed` | OrderList, ArticleList | – | yes | yes | – |
| `DownloadDone` | OrderList | – | yes | yes | – |
| `Articles` | ArticleList | – | – | – | yes |
| `PrdNumber` | ArticleList | yes | – | – | – |
| `PrdThumbnailURL` | ArticleList | yes | yes | yes | – |
| `File` | ArticleList | yes | – | – | – |
| `FileSize` | ArticleList | yes | – | – | – |
| `DownloadsDone` | ArticleList | yes | – | – | – |
| `Downloads` | ArticleList | yes | – | – | – |
| `ValidDateTime` | ArticleList | yes | – | – | – |
| `DownloadUrl` | ArticleList | yes | – | – | – |
| `ddwrnclass` | ArticleList | yes | – | – | – |
| `vdwrnclass` | ArticleList | yes | – | – | – |
| `Back` | ArticleList | – | yes | yes | – |

All tags are permitted exclusively in the download template, each within the specified section.

## Related topics

* Guide: Offering download products
* Guide: Upload module
* Guide: Customer account


## Related topics

- [Offering download products](https://dokumentation.websale.de/en/v8s/produkte/download-produkte-anbieten.md)
- [Multiple addresses: tags per template](https://dokumentation.websale.de/en/v8s/referenz/tags/multiple-adressen.md)
- [Templates: fundamentals](https://dokumentation.websale.de/en/v8s/grundlagen-templates/templates-grundlagen.md)
- [Purchase vouchers for printing](https://dokumentation.websale.de/en/v8s/gutscheine-anbieten/kaufgutscheine-zum-ausdrucken.md)
- [Basics of tags](https://dokumentation.websale.de/en/v8s/grundlagen-zu-tags.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.