laterite-admin 0.9.21

Laterite CMF admin surface: the Axum router, session middleware, and login shell
Documentation
<div class="lat-split lat-split--aside">
  <div class="lat-pane">
    <div class="lat-media-preview">{% if file.is_image %}<img src="{{ file.preview_url }}" alt="{{ alt }}">{% else %}<span class="lat-media-card__kind">{{ file.kind }}</span>{% endif %}</div>
    <div class="lat-pane__body">
      <table class="lat-media-facts">
        <tbody>
          <tr><th>{{ shell.t("Type") }}</th><td>{{ file.content_type }}</td></tr>
          <tr><th>{{ shell.t("Size") }}</th><td>{{ file.size }}</td></tr>
          {% if !dimensions.is_empty() %}<tr><th>{{ shell.t("Dimensions") }}</th><td>{{ dimensions }}</td></tr>{% endif %}
          <tr><th>{{ shell.t("Uploaded") }}</th><td>{{ uploaded }}</td></tr>
          <tr><th>{{ shell.t("Disk") }}</th><td>{{ disk }}</td></tr>
          <tr><th>{{ shell.t("URL") }}</th><td><code>{{ file.url }}</code></td></tr>
          <tr><th>{{ shell.t("Hash") }}</th><td><code>{{ hash }}</code></td></tr>
        </tbody>
      </table>
    </div>
  </div>
  <div>
    <form class="lat-pane" method="post" action="{{ file_href }}/update">
      <div class="lat-pane__head">{{ shell.t("Details") }}</div>
      <div class="lat-pane__body">
        <input type="hidden" name="_csrf" value="{{ shell.csrf_token() }}">
        <div class="lat-field">
          <label class="lat-field__label" for="name">{{ shell.t("File name") }}</label>
          <input class="lat-input" id="name" name="name" value="{{ original_name }}" required{% if !may_manage %} readonly{% endif %}>
        </div>
        <div class="lat-field">
          <label class="lat-field__label" for="title">{{ shell.t("Title") }}</label>
          <input class="lat-input" id="title" name="title" value="{{ title }}"{% if !may_manage %} readonly{% endif %}>
        </div>
        <div class="lat-field">
          <label class="lat-field__label" for="alt">{{ shell.t("Alt text") }}</label>
          <input class="lat-input" id="alt" name="alt" value="{{ alt }}"{% if !may_manage %} readonly{% endif %}>
          <p class="lat-field__help" style="margin-bottom:0">{{ shell.t("What the image shows, for readers who cannot see it.") }}</p>
        </div>
      </div>
      {% if may_manage %}<div class="lat-pane__foot"><button class="lat-btn lat-btn--primary" type="submit">{{ shell.t("Save") }}</button></div>{% endif %}
    </form>
    {% if may_manage %}
    <form class="lat-pane" method="post" action="{{ file_href }}/move">
      <div class="lat-pane__head">{{ shell.t("Folder") }}</div>
      <div class="lat-pane__body">
        <input type="hidden" name="_csrf" value="{{ shell.csrf_token() }}">
        <div class="lat-field">
          <label class="lat-field__label lat-visually-hidden" for="to">{{ shell.t("Folder") }}</label>
          <select class="lat-input lat-select" id="to" name="to">
            <option value=""{% if folder.is_empty() %} selected{% endif %}>/</option>
            {% for f in folders %}<option value="{{ f.id }}"{% if folder == f.id %} selected{% endif %}>{{ f.path }}</option>{% endfor %}
          </select>
        </div>
      </div>
      <div class="lat-pane__foot"><button class="lat-btn lat-btn--secondary" type="submit">{{ shell.t("Move") }}</button></div>
    </form>
    {% endif %}
    <div class="lat-pane">
      <div class="lat-pane__head">{{ shell.t("Used by") }}</div>
      {% if users.is_empty() %}
      <div class="lat-pane__body"><p class="lat-help" style="margin:0">{{ shell.t("No record links to this file.") }}</p></div>
      {% else %}
      <table class="lat-table"><tbody>
        {% for u in users %}<tr><td>{{ u.owner_type }}</td><td>{{ u.owner_id }}</td><td>{{ u.field }}</td></tr>{% endfor %}
      </tbody></table>
      {% endif %}
    </div>
  </div>
</div>
{% if may_crop %}
<dialog class="lat-dialog lat-dialog--pick" id="crop-image">
  <form method="post" action="{{ file_href }}/crop" class="lat-crop" data-lat-widget="crop" data-width="{{ width }}" data-height="{{ height }}">
    {% let dialog_title = shell.t("Crop image") %}{% include "_dialog_head.html" %}
    <div class="lat-dialog__body lat-dialog__body--flush">
      <input type="hidden" name="_csrf" value="{{ shell.csrf_token() }}">
      <input type="hidden" name="x" value="0" data-crop-x>
      <input type="hidden" name="y" value="0" data-crop-y>
      <input type="hidden" name="w" value="{{ width }}" data-crop-w>
      <input type="hidden" name="h" value="{{ height }}" data-crop-h>
      <div class="lat-pane__bar">
        <label class="lat-crop__aspect">{{ shell.t("Aspect") }}
          <select class="lat-input lat-select" data-crop-aspect aria-label='{{ shell.t("Aspect") }}'>
            <option value="0">{{ shell.t("Free") }}</option>
            <option value="1">1:1</option>
            <option value="1.3333">4:3</option>
            <option value="1.5">3:2</option>
            <option value="1.7778">16:9</option>
            <option value="original">{{ shell.t("As the original") }}</option>
          </select>
        </label>
        <span class="lat-help" style="margin:0"><span data-crop-size>{{ width }} × {{ height }}</span> {{ shell.t("of") }} {{ width }} × {{ height }}</span>
        <button type="button" class="lat-btn lat-btn--ghost lat-btn--sm" data-crop-reset style="margin-left:auto">{{ shell.t("Whole image") }}</button>
      </div>
      <div class="lat-crop__stage" data-crop-stage>
        <img src="{{ file.preview_url }}" alt="" draggable="false" data-crop-image>
        <div class="lat-crop__box" data-crop-box><span class="lat-crop__handle" data-crop-handle></span></div>
      </div>
      <div class="lat-pane__bar">
        <label class="lat-check"><input type="radio" name="mode" value="new" checked> {{ shell.t("Save as a new file") }}</label>
        <label class="lat-check"><input type="radio" name="mode" value="replace"> {{ shell.t("Replace this file") }}</label>
      </div>
    </div>
    <div class="lat-dialog__actions"><button class="lat-btn lat-btn--ghost" type="button" data-lat-dialog-close>{{ shell.t("Cancel") }}</button><button class="lat-btn lat-btn--primary" type="submit">{{ shell.t("Crop") }}</button></div>
  </form>
</dialog>
{% endif %}