> ## 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.

# Upload module: tags

> Build the template of the upload module: query the upload ID, list order items, display and delete uploaded files, accept new files, complete uploads and output the log.

For printed products, promotional items or custom-made articles, it is not the shop that supplies the data but the buyer. After ordering, they upload their files, one or more per order item, and report at the end that they are done. This is handled by the upload module, a separate program alongside the shop.

Its interface is created from exactly one template, usually `ws_upload.htm`. This template contains the placeholders on this page. They follow the same structure as shop template tags, but they belong to the upload program and not to the shop.

* Guide: Integrating the upload module
* Reference: wsupload.config

> [!WARNING]
>
> Not a single shop template tag works in this template, neither `PR-`, nor `BASKET-`, nor `WS-`. Conversely, the placeholders on this page have no meaning in the shop. The notation is the same: `~Name~` for a value, `{Name}` and `{/Name}` for a range, `{@Name}` and `{/@Name}` for a loop.

## Three views in one template

The upload program shows three views one after the other, and all three are contained in the same file. The program decides which one appears; the template only supplies the building blocks.

| Range | View |
| - | - |
| `{UplIdInput}` | the query for the upload ID or the order number |
| `{ItemList}` | the list of order items |
| `{Item}` | a single order item with its files |

> [!NOTE]
>
> If an order has only a single item, the program skips the list and shows `{Item}` immediately. The `{ItemList}` range then does not appear at all. Build both anyway, because the same file serves both cases.

> [!WARNING]
>
> Everything outside these three ranges appears on every view. This is the right place for the header and footer, for `{Msg}` and for `~WSUploadScripts~`.

## Two operating modes

The upload module works not only after an order but also for inquiries via the inquiry form. This inquiry upload has no order items and therefore not all placeholders.

> [!WARNING]
>
> About half of the placeholders are not available for the inquiry upload. This affects all placeholders that require an order or an item. The overview table at the end of the page lists this for each placeholder. If you want to serve both operating modes with one template, restrict yourself to the placeholders that apply in both.

## The page frame

These placeholders can be placed anywhere in the template and describe the environment.

| Placeholder | Returns |
| - | - |
| `protocol` | `https` in SSL mode, otherwise `http` |
| `hostname` | the host name via which the upload program was called |
| `baseurl` | the base address of the template directory |
| `charset` | the character set from the shop configuration |
| `CommonId` | the shop ID |
| `WSUploadScripts` | the scripts that cannot be moved to external files |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=~charset~">
   <base href="~protocol~://~hostname~~baseurl~">
</head>
<body>
~WSUploadScripts~
```

> [!WARNING]
>
> `~WSUploadScripts~` is not optional. Without this placeholder, the template lacks the scripts for the progress display, cancellation and the selection of the intended use. Set it once, as early as possible in the `body`.

> [!NOTE]
>
> According to the previous documentation, `protocol` and `hostname` are only permitted within the log loop. The reference template uses both in the `base` element in the page header, and that is exactly where they belong. The restriction in the source is too narrow.

### Messages

| Placeholder | Meaning |
| - | - |
| `Msg` | the current notice or error message, as a range and as a value |
| `{UploadSuccess}` | Range: the last upload was successful |

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

{UploadSuccess}
   <p class="ok">Ihre Datei wurde übertragen.</p>
{/UploadSuccess}
```

## Querying the upload ID or order number

If someone calls the upload program without an identifier, `{UplIdInput}` appears. There the buyer enters either the upload ID from their order confirmation or their order number.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{UplIdInput}
   <form name="idform" method="post" action="~cgiurl~" accept-charset="ISO-8859-1">
      <label>Upload-ID <input type="text" name="UploadId" value="~UploadId~"></label>
      <label>oder Auftragsnummer <input type="text" name="Ordernumber" value="~Ordernumber~"></label>
      <input type="submit" name="OkBtn" value="OK">
   </form>
{/UplIdInput}
```

| Placeholder | Meaning |
| - | - |
| `{UplIdInput}` | Range: neither an upload ID nor an order number is available |
| `UploadId` | the upload ID of the order |
| `Ordernumber` | the order number |
| `{OrdNumMode}` | Range: the process works with the order number instead of the upload ID |

> [!NOTE]
>
> The upload program assigns an upload ID per order and additionally an item ID per order item. The buyer receives the upload ID; they do not need to know the item ID.

> [!NOTE]
>
> The names of the two input fields are fixed and are `UploadId` and `Ordernumber`. There are no `_input` placeholders here as in the shop; write the names directly into the template.

> [!NOTE]
>
> Use `{OrdNumMode}` to label the display appropriately. If the process works via the order number, it is not very helpful to show the buyer an upload ID that they cannot find anywhere.

## The list of order items

If the order has several items, `{ItemList}` shows the overview. `{@PrdData}` loops over the items within it.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{ItemList}
   <table>
      {@PrdData}
         <tr>
            <td>~PrdName~</td>
            <td>~PrdNumber~</td>
            <td>~PosID~</td>
            <td>
               <a href="~PrdEdtLink~">bearbeiten</a>
               {PosLocked}<span>Upload abgeschlossen</span>{/PosLocked}
               {!PosLocked}
                  {HasFile}Datei vorhanden{/HasFile}
                  {!HasFile}noch keine Datei{/!HasFile}
               {/!PosLocked}
            </td>
         </tr>
      {/@PrdData}
   </table>
{/ItemList}
```

| Placeholder | Returns | Located in |
| - | - | - |
| `{ItemList}` | the range of the item list | anywhere |
| `{@PrdData}` | the loop over the items | `{ItemList}` |
| `PrdName` | the product name | `{@PrdData}` or `{Item}` |
| `PrdNumber` | the product number | `{@PrdData}` or `{Item}` |
| `PosID` | the item ID | `{@PrdData}` or `{Item}` |
| `PrdEdtLink` | the link to the detail view of this item | `{@PrdData}` |
| `{HasFile}` | Range: a file already exists for this item | `{@PrdData}` |
| `{PosLocked}` | Range: the upload for this item is completed | `{@PrdData}` or `{Item}` |

> [!NOTE]
>
> `{HasFile}` answers the question for the one item in the iteration, `{HasFiles}` further below for the entire order or the displayed item. The two names differ only in the final s, but the meaning is different.

> [!WARNING]
>
> `{PosLocked}` also applies when not this item but the entire order has been completed. This is intentional, because the result is the same for the buyer. To distinguish the two, additionally use `{UploadLocked}`.

### Back to the list

| Placeholder | Meaning |
| - | - |
| `ItemListLink` | the address of the item list, also a range |
| `{MultiplePositions}` | Range: the order has more than one item |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{ItemListLink}
   <p><a href="~ItemListLink~">Zurück zur Liste der Bestellpositionen</a></p>
{/ItemListLink}
```

> [!NOTE]
>
> Both only apply if the order has more than one item. With a single item, there would be nowhere for the link to lead. `ItemListLink` is therefore both a value and a bracketing, which is also how the previous documentation specifies this tag.

## An item with its files

`{Item}` is the detail view. It contains everything relating to a single order item.

### The existing files

`{@Files}` loops over the files that have already been uploaded for this item.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{Item}
   <form name="delform" method="post" action="~cgiurl~" accept-charset="ISO-8859-1">
      <table>
         {@Files}
            <tr>
               <td>~FileName~</td>
               <td>~FileSize~ MB</td>
               <td>~UploadDate~ ~UploadTime~</td>
               <td>
                  <input type="checkbox" name="~FileMarkBoxName~" value="marked">
                  <input type="hidden" name="~FileNameName~" value="~FileName~">
               </td>
            </tr>
         {/@Files}

         {HasFiles}
            <tr>
               <td colspan="3">Gesamt ~TotalSize~ MB von höchstens ~PositionLimitMB~ MB</td>
               <td><input type="submit" name="DelBtn" value="Löschen"></td>
            </tr>
         {/HasFiles}

         {NoFiles}
            <tr><td colspan="4">Noch keine Dateien vorhanden.</td></tr>
         {/NoFiles}
      </table>
   </form>
{/Item}
```

| Placeholder | Returns | Located in |
| - | - | - |
| `{@Files}` | the loop over the existing files | `{Item}` |
| `FileName` | the file name | `{@Files}` or `{@LogLines}` |
| `FileSize` | the size in MB | `{@Files}` |
| `UploadDate` | the date of the upload | `{@Files}` |
| `UploadTime` | the time of the upload | `{@Files}` |
| `FileMarkBoxName` | the name of the checkbox for deleting | `{@Files}` |
| `FileNameName` | the name of the hidden field with the file name | `{@Files}` |
| `TotalSize` | the total size of all files of this item in MB | `{Item}` |
| `{HasFiles}` | Range: files are available | anywhere |
| `{NoFiles}` | Range: no files are available | anywhere |
| `editurl` | the address of the edit and delete form | anywhere |
| `delurl` | the address for deleting | anywhere |

> [!WARNING]
>
> Both fields belong together for deleting. The checkbox from `FileMarkBoxName` marks the file, and the hidden field from `FileNameName` passes the corresponding file name. If you omit one of them, the selection does not reach the program.

> [!NOTE]
>
> `{NoFiles}` is intended to be placed after `{HasFiles}`. The two ranges are mutually exclusive, so `{NoFiles}` is the more readable form of the negative bracketing of `{HasFiles}`.

### The intended use per file

For each file, you can store what it is intended for, for example front side, back side or proof. The selection options are defined in the `<+FileInfo>` subsections of the `<Upload>` section in `wsupload.config`.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{@Files}
   <select name="~FileInfoSelName~" id="~FileInfoSelName~"
           onchange="fileInfoChanged('~FileName~', $(this).val(), '~FileInfoProcId~');">
      ~fileinfoopts~
   </select>
   <img src="~baseurl~images/ws-loading.gif" id="~FileInfoProcId~" style="visibility: hidden;" alt="">
{/@Files}
```

| Placeholder | Returns | Located in |
| - | - | - |
| `fileinfoopts` | the options with the file's preselection | `{@Files}` |
| `uplfileinfoopts` | the same options without preselection | anywhere |
| `FileInfoSelName` | name and ID of the selection field | `{@Files}` |
| `FileInfoProcId` | the ID of the loading graphic | `{@Files}` |

> [!NOTE]
>
> The difference between the two option lists is the preselection. `fileinfoopts` belongs to a file that has already been uploaded and has its intended use preselected, `uplfileinfoopts` belongs to the field for the new file and has nothing preselected.

> [!NOTE]
>
> Changing the intended use happens in the background without reloading the page. Hence the loading graphic, which is addressed via `FileInfoProcId`. The entire group is optional. If you do not need an intended use, omit all four placeholders.

## Uploading a new file

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{!UploadLocked}
   {Web2Print}
      <p>Die Druckdaten dieser Bestellung entstehen online, ein Upload ist nicht nötig.</p>
   {/Web2Print}

   {!Web2Print}
      <form name="uplform" enctype="multipart/form-data" method="post" action="~uplurl~" accept-charset="ISO-8859-1">
         <input type="file" name="uplfile">
         <select name="uplfileinfo">~uplfileinfoopts~</select>
         <input type="submit" name="UploadBtn" value="Transfer starten">
      </form>
   {/!Web2Print}
{/!UploadLocked}
```

| Placeholder | Meaning |
| - | - |
| `uplurl` | the address to which the upload form submits |
| `uploadUrl` | the same purpose in the newer version of the module |
| `{Web2Print}` | Range: the data is created online and not uploaded |
| `{UploadLocked}` | Range: the upload is completed and locked |

> [!WARNING]
>
> The name of the file field is fixed and is `uplfile`, that of the intended use field is `uplfileinfo`. Neither exists as a placeholder; write them directly into the template.

> [!NOTE]
>
> `uploadUrl` belongs to the newer version of the upload module, which uploads via a JavaScript plugin, and replaces `uplurl` there. Which version your shop uses depends on the embedded script and the structure of the form. Do not mix the two.

> [!WARNING]
>
> The reference template does not bracket the upload form with `{!Web2Print}` but with a commented-out `{!Web2PrintX}`, which does not exist. For a web-to-print order, both the notice and the form therefore appear there. The example above sets the bracketing correctly.

## The limits

| Placeholder | Returns |
| - | - |
| `FileLimitMB` | the maximum permitted size of a single file in MB |
| `PositionLimitMB` | the maximum permitted total size per order item in MB |
| `PositionLimitCount` | the maximum permitted number of files per order item |
| `NewUplLink` | the link for a new attempt after an error |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<p>Je Datei höchstens ~FileLimitMB~ MB, je Position höchstens
   ~PositionLimitCount~ Dateien mit zusammen ~PositionLimitMB~ MB.</p>
```

> [!NOTE]
>
> These three values are stored by WEBSALE technical support and agreed with the shop operator. Output them in the template instead of writing numbers into it; then the text is still correct after a change.

> [!NOTE]
>
> `NewUplLink` is intended for the error case, for example for the notice when the file size has been exceeded. It leads back to the upload page of the same item.

## Rejected files

The upload program checks each file for its MIME type and for malware. If a check is triggered, the corresponding range appears.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{MimeTypeMismatch}
   <p class="fehler">
      Die Datei ~FailedFile~ passt nicht zu ihrer Endung. Erkannt wurde
      der Typ ~MimeType~ bei der Endung ~FileExtension~.
   </p>
{/MimeTypeMismatch}

{VirusDetected}
   <p class="fehler">Die Datei ~FailedFile~ wurde abgewiesen.</p>
{/VirusDetected}
```

| Placeholder | Meaning | Located in |
| - | - | - |
| `{MimeTypeMismatch}` | Range: the MIME type check was triggered | anywhere |
| `{VirusDetected}` | Range: the virus scan was triggered | anywhere |
| `FailedFile` | the name of the rejected file | both ranges |
| `MimeType` | the detected MIME type | `{MimeTypeMismatch}` |
| `FileExtension` | the file extension | `{MimeTypeMismatch}` |

> [!WARNING]
>
> Both ranges only appear if the respective check is classified as an **error** in the configuration. If it is only switched on for monitoring, it is triggered, but the range remains empty. This is not stated in the previous documentation and explains the case where a file is rejected without the template displaying anything.

> [!WARNING]
>
> The supplied reference template contains neither `{MimeTypeMismatch}` nor `{VirusDetected}`. Anyone who adopts it unchanged has no display for these two cases. Add both ranges.

## Completing and reopening

At the end, the buyer confirms that they have supplied all files. After that, the program no longer accepts anything. This can be done either for the entire order or per item.

| Placeholder | Meaning |
| - | - |
| `{AllPosLock}` | Range: completion applies to the entire order |
| `{SinglePosLock}` | Range: completion is possible per item |
| `{UploadsComplete}` | Range: at least one file exists for every item |
| `{UploadLocked}` | Range: the order is completed |
| `{PosLocked}` | Range: this item is completed |
| `{Unlock}` | Range: the completion of the order can be reversed |
| `{UnlockPos}` | Range: the completion of this item can be reversed |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{AllPosLock}
   {HasFiles}
      {!UploadLocked}
         {UploadsComplete}
            <form name="lockform" method="post" action="~lockurl~" accept-charset="ISO-8859-1">
               <input type="submit" name="LockBtn" value="Uploads abschließen">
               <p>
                  Danach können Sie keine weiteren Daten zu diesem Auftrag senden.
               </p>
            </form>
         {/UploadsComplete}
         {!UploadsComplete}
            <p>Es gibt noch Positionen ohne Datei.</p>
         {/!UploadsComplete}
      {/!UploadLocked}
   {/HasFiles}
{/AllPosLock}
```

> [!NOTE]
>
> `{AllPosLock}` and `{SinglePosLock}` are not decided by the template but by the operating mode stored in the module's configuration. There are three options: completion only for the entire order, only per item, or both at once. The default is completion for the entire order. Include both ranges, and the template works in every operating mode.

> [!WARNING]
>
> The nesting in the example is not decoration but necessary. The completion button only belongs on the page if files are available, the upload is not yet locked and there is something for every item. If one of the three bracketings is missing, the page offers a button that either does nothing or locks too early.

### The form addresses

| Placeholder | Form | Located in |
| - | - | - |
| `lockurl` | complete the order's uploads | `{Item}` |
| `ordlockurl` | the same from within the item list | `{ItemList}` |
| `poslockurl` | complete the upload of an item | `{@PrdData}` or `{Item}` |
| `unlockurl` | reverse the completion of the order | `{Unlock}` |
| `unlockposurl` | reverse the completion of an item | `{UnlockPos}` |

> [!NOTE]
>
> Within the item loop, `poslockurl` refers to the item in the iteration and outside it to the displayed item. This is why the same placeholder works in both places.

> [!NOTE]
>
> `lockurl` and `ordlockurl` do the same thing but are intended for different views. Use one in `{ItemList}` and the other in `{Item}`, as specified in the column above.

### Reversing the completion

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{AllPosLock}
   {Unlock}
      <form name="unlockform" method="post" action="~unlockurl~" accept-charset="ISO-8859-1">
         <input type="submit" name="UnlockBtn" value="Abschluss aufheben">
      </form>
   {/Unlock}
{/AllPosLock}

{SinglePosLock}
   {UnlockPos}
      <form name="unlockposform" method="post" action="~unlockposurl~" accept-charset="ISO-8859-1">
         <input type="submit" name="UnlockBtn" value="Abschluss dieser Position aufheben">
      </form>
   {/UnlockPos}
{/SinglePosLock}
```

> [!WARNING]
>
> Both ranges only apply if the upload program was called with the parameter `unlockallow=Y` **and** the respective completion actually exists. Without this parameter, they remain silent even if everything else fits.

> [!NOTE]
>
> Reversing is intended for the case where the buyer subsequently finds an error in their data and production has not yet started.

## The log

The program keeps a log for each process, which can be output in the template.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{Logging}
   <table>
      {@LogLines}
         <tr>
            <td>~Date~ ~Time~</td>
            <td>~Type~</td>
            <td>~FileName~</td>
         </tr>
      {/@LogLines}
   </table>
{/Logging}
```

| Placeholder | Returns | Located in |
| - | - | - |
| `{Logging}` | Range: log data is available | anywhere |
| `{@LogLines}` | the loop over the log lines | `{Logging}` |
| `Date` | the date of the entry | `{@LogLines}` |
| `Time` | the time of the entry | `{@LogLines}` |
| `Type` | the description of the process | `{@LogLines}` |
| `FileName` | the file concerned | `{@LogLines}` |

> [!NOTE]
>
> `Type` is already readable text such as "Datei hochgeladen" (file uploaded) or "Datei gelöscht" (file deleted), not a technical code.

> [!NOTE]
>
> `FileName` appears both in the file loop and in the log loop and refers in each case to the file of the current iteration. It is the only placeholder shared by two loops.

## The placeholders at a glance

| Placeholder | Single tag | Range tag | Negative range tag | Loop tag | Located in | Inquiry upload |
| - | - | - | - | - | - | - |
| `protocol` | yes | – | – | – | anywhere | no |
| `hostname` | yes | – | – | – | anywhere | no |
| `baseurl` | yes | – | – | – | anywhere | yes |
| `charset` | yes | – | – | – | anywhere | no |
| `CommonId` | yes | – | – | – | anywhere | no |
| `WSUploadScripts` | yes | – | – | – | anywhere | no |
| `Msg` | yes | yes | yes | – | anywhere | no |
| `UploadSuccess` | – | yes | yes | – | anywhere | yes |
| `UplIdInput` | – | yes | yes | – | anywhere | no |
| `UploadId` | yes | – | – | – | anywhere | no |
| `Ordernumber` | yes | – | – | – | anywhere | no |
| `OrdNumMode` | – | yes | yes | – | anywhere | no |
| `ItemList` | – | yes | – | – | anywhere | no |
| `PrdData` | – | – | – | yes | `{ItemList}` | no |
| `PrdName` | yes | – | – | – | `{@PrdData}` or `{Item}` | no |
| `PrdNumber` | yes | – | – | – | `{@PrdData}` or `{Item}` | no |
| `PosID` | yes | – | – | – | `{@PrdData}` or `{Item}` | no |
| `PrdEdtLink` | yes | – | – | – | `{@PrdData}` | no |
| `HasFile` | – | yes | yes | – | `{@PrdData}` | no |
| `ItemListLink` | yes | yes | – | – | anywhere | no |
| `MultiplePositions` | – | yes | yes | – | anywhere | no |
| `Item` | – | yes | – | – | anywhere | yes |
| `Files` | – | – | – | yes | `{Item}` | yes |
| `FileName` | yes | – | – | – | `{@Files}` or `{@LogLines}` | yes |
| `FileSize` | yes | – | – | – | `{@Files}` | yes |
| `UploadDate` | yes | – | – | – | `{@Files}` | yes |
| `UploadTime` | yes | – | – | – | `{@Files}` | yes |
| `FileMarkBoxName` | yes | – | – | – | `{@Files}` | yes |
| `FileNameName` | yes | – | – | – | `{@Files}` | yes |
| `TotalSize` | yes | – | – | – | `{Item}` | yes |
| `HasFiles` | – | yes | yes | – | anywhere | yes |
| `NoFiles` | – | yes | – | – | anywhere | no |
| `editurl` | yes | – | – | – | anywhere | yes |
| `delurl` | yes | – | – | – | anywhere | yes |
| `fileinfoopts` | yes | – | – | – | `{@Files}` | no |
| `uplfileinfoopts` | yes | – | – | – | anywhere | no |
| `FileInfoSelName` | yes | – | – | – | `{@Files}` | no |
| `FileInfoProcId` | yes | – | – | – | `{@Files}` | no |
| `uplurl` | yes | – | – | – | anywhere | yes |
| `uploadUrl` | yes | – | – | – | anywhere | no |
| `Web2Print` | – | yes | yes | – | `{Item}` | no |
| `FileLimitMB` | yes | – | – | – | anywhere | yes |
| `PositionLimitMB` | yes | – | – | – | anywhere | yes |
| `PositionLimitCount` | yes | – | – | – | anywhere | yes |
| `NewUplLink` | yes | – | – | – | anywhere | yes |
| `MimeTypeMismatch` | – | yes | – | – | anywhere | yes |
| `VirusDetected` | – | yes | – | – | anywhere | yes |
| `FailedFile` | yes | – | – | – | both error ranges | yes |
| `MimeType` | yes | – | – | – | `{MimeTypeMismatch}` | yes |
| `FileExtension` | yes | – | – | – | `{MimeTypeMismatch}` | yes |
| `AllPosLock` | – | yes | – | – | `{Item}` or `{ItemList}` | no |
| `SinglePosLock` | – | yes | – | – | `{Item}` or `{ItemList}` | no |
| `UploadsComplete` | – | yes | yes | – | anywhere | no |
| `UploadLocked` | – | yes | yes | – | anywhere | no |
| `PosLocked` | – | yes | yes | – | `{@PrdData}` or `{Item}` | no |
| `Unlock` | – | yes | yes | – | anywhere | no |
| `UnlockPos` | – | yes | – | – | `{Item}` | no |
| `lockurl` | yes | – | – | – | `{Item}` | yes |
| `ordlockurl` | yes | – | – | – | `{@PrdData}` | yes |
| `poslockurl` | yes | – | – | – | `{@PrdData}` or `{Item}` | yes |
| `unlockurl` | yes | – | – | – | `{Unlock}` | yes |
| `unlockposurl` | yes | – | – | – | `{UnlockPos}` | yes |
| `Logging` | – | yes | – | – | anywhere | no |
| `LogLines` | – | – | – | yes | `{Logging}` | no |
| `Date` | yes | – | – | – | `{@LogLines}` | no |
| `Time` | yes | – | – | – | `{@LogLines}` | no |
| `Type` | yes | – | – | – | `{@LogLines}` | no |

> [!NOTE]
>
> The "Located in" column names the range or loop within which the placeholder must be placed. "anywhere" means at any position in the template. The "Inquiry upload" column states whether the placeholder is also available for uploads from the inquiry form.

## Further placeholders in the reference template

The supplied template uses three placeholders that are not described in the previous documentation.

| Placeholder | Purpose |
| - | - |
| `cgiurl` | the address of the upload program, for forms without their own target |
| `progressurl` | the address for the progress display |
| `cancelurl` | the address for cancelling a running transfer |

> [!NOTE]
>
> You only need these three if you rebuild the progress display and cancellation in the template. The reference template shows how they work together. For a simple upload form, the placeholders from the overview above are sufficient.

## Related topics

* Guide: Integrating the upload module
* Reference: wsupload.config
* Reference: SENDUPLOADLINK- (Sending the upload link by email)


## Related topics

- [Wish list, comparison, upload and external services](https://dokumentation.websale.de/en/v8s/referenz/tags/ws/merkzettel-vergleich-upload-und-externe-dienste.md)
- [Download template: tags](https://dokumentation.websale.de/en/v8s/referenz/tags/download-template-tags.md)
- [Buttons for customer account and login](https://dokumentation.websale.de/en/v8s/referenz/tags/bt/kundenkonto-und-anmeldung.md)
- [Clothing module](https://dokumentation.websale.de/en/v8s/kategorien/bekleidungsmodul.md)
- [E-PIA_ (Upload)](https://dokumentation.websale.de/en/v8s/referenz/tags/e-pia/upload.md)


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