Custom pages: Implement adding custom markdown pages to the site navigation
This commit is contained in:
parent
9f6346a373
commit
fb0d44f132
|
@ -34,4 +34,5 @@ linx-genkey
|
||||||
files/
|
files/
|
||||||
meta/
|
meta/
|
||||||
binaries/
|
binaries/
|
||||||
|
custom_pages/
|
||||||
authfile
|
authfile
|
||||||
|
|
|
@ -56,6 +56,7 @@ allowhotlink = true
|
||||||
- ```-remoteuploads``` -- (optionally) enable remote uploads (/upload?url=https://...)
|
- ```-remoteuploads``` -- (optionally) enable remote uploads (/upload?url=https://...)
|
||||||
- ```-nologs``` -- (optionally) disable request logs in stdout
|
- ```-nologs``` -- (optionally) disable request logs in stdout
|
||||||
- ```-force-random-filename``` -- (optionally) force the use of random filenames
|
- ```-force-random-filename``` -- (optionally) force the use of random filenames
|
||||||
|
- ```-custompagespath "custom_pages"``` -- (optionally) specify path to directory containing markdown pages (must end in .md) that will be added to the site navigation (this can be useful for providing contact/support information and so on). For example, custom_pages/My_Page.md will become My Page in the site navigation
|
||||||
|
|
||||||
#### Require API Keys for uploads
|
#### Require API Keys for uploads
|
||||||
- ```-authfile path/to/authfile``` -- (optionally) require authorization for upload/delete by providing a newline-separated file of scrypted auth keys
|
- ```-authfile path/to/authfile``` -- (optionally) require authorization for upload/delete by providing a newline-separated file of scrypted auth keys
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/microcosm-cc/bluemonday"
|
||||||
|
"github.com/russross/blackfriday"
|
||||||
|
)
|
||||||
|
|
||||||
|
func initializeCustomPages(customPagesDir string) {
|
||||||
|
files, err := ioutil.ReadDir(customPagesDir)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error reading the custom pages directory: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, file := range files {
|
||||||
|
fileName := file.Name()
|
||||||
|
|
||||||
|
if len(fileName) <= 3 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.EqualFold(string(fileName[len(fileName)-3:len(fileName)]), ".md") {
|
||||||
|
contents, err := ioutil.ReadFile(path.Join(customPagesDir, fileName))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error reading file %s", fileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe := blackfriday.MarkdownCommon(contents)
|
||||||
|
html := bluemonday.UGCPolicy().SanitizeBytes(unsafe)
|
||||||
|
|
||||||
|
fileName := fileName[0 : len(fileName)-3]
|
||||||
|
customPages[fileName] = string(html)
|
||||||
|
customPagesNames[fileName] = strings.ReplaceAll(fileName, "_", " ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
pages.go
15
pages.go
|
@ -50,6 +50,21 @@ func apiDocHandler(c web.C, w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeCustomPageHandler(fileName string) func(c web.C, w http.ResponseWriter, r *http.Request) {
|
||||||
|
return func(c web.C, w http.ResponseWriter, r *http.Request) {
|
||||||
|
err := renderTemplate(Templates["custom_page.html"], pongo2.Context{
|
||||||
|
"siteurl": getSiteURL(r),
|
||||||
|
"forcerandom": Config.forceRandomFilename,
|
||||||
|
"contents": customPages[fileName],
|
||||||
|
"filename": fileName,
|
||||||
|
"pagename": customPagesNames[fileName],
|
||||||
|
}, r, w)
|
||||||
|
if err != nil {
|
||||||
|
oopsHandler(c, w, r, RespHTML, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func notFoundHandler(c web.C, w http.ResponseWriter, r *http.Request) {
|
func notFoundHandler(c web.C, w http.ResponseWriter, r *http.Request) {
|
||||||
w.WriteHeader(404)
|
w.WriteHeader(404)
|
||||||
err := renderTemplate(Templates["404.html"], pongo2.Context{}, r, w)
|
err := renderTemplate(Templates["404.html"], pongo2.Context{}, r, w)
|
||||||
|
|
13
server.go
13
server.go
|
@ -70,6 +70,7 @@ var Config struct {
|
||||||
s3ForcePathStyle bool
|
s3ForcePathStyle bool
|
||||||
forceRandomFilename bool
|
forceRandomFilename bool
|
||||||
accessKeyCookieExpiry uint64
|
accessKeyCookieExpiry uint64
|
||||||
|
customPagesDir string
|
||||||
}
|
}
|
||||||
|
|
||||||
var Templates = make(map[string]*pongo2.Template)
|
var Templates = make(map[string]*pongo2.Template)
|
||||||
|
@ -80,6 +81,8 @@ var timeStartedStr string
|
||||||
var remoteAuthKeys []string
|
var remoteAuthKeys []string
|
||||||
var metaStorageBackend backends.MetaStorageBackend
|
var metaStorageBackend backends.MetaStorageBackend
|
||||||
var storageBackend backends.StorageBackend
|
var storageBackend backends.StorageBackend
|
||||||
|
var customPages = make(map[string]string)
|
||||||
|
var customPagesNames = make(map[string]string)
|
||||||
|
|
||||||
func setup() *web.Mux {
|
func setup() *web.Mux {
|
||||||
mux := web.New()
|
mux := web.New()
|
||||||
|
@ -227,6 +230,14 @@ func setup() *web.Mux {
|
||||||
mux.Get(selifIndexRe, unauthorizedHandler)
|
mux.Get(selifIndexRe, unauthorizedHandler)
|
||||||
mux.Get(torrentRe, fileTorrentHandler)
|
mux.Get(torrentRe, fileTorrentHandler)
|
||||||
|
|
||||||
|
if Config.customPagesDir != "" {
|
||||||
|
initializeCustomPages(Config.customPagesDir)
|
||||||
|
for fileName := range customPagesNames {
|
||||||
|
mux.Get(Config.sitePath+fileName, makeCustomPageHandler(fileName))
|
||||||
|
mux.Get(Config.sitePath+fileName+"/", makeCustomPageHandler(fileName))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mux.NotFound(notFoundHandler)
|
mux.NotFound(notFoundHandler)
|
||||||
|
|
||||||
return mux
|
return mux
|
||||||
|
@ -298,6 +309,8 @@ func main() {
|
||||||
flag.BoolVar(&Config.forceRandomFilename, "force-random-filename", false,
|
flag.BoolVar(&Config.forceRandomFilename, "force-random-filename", false,
|
||||||
"Force all uploads to use a random filename")
|
"Force all uploads to use a random filename")
|
||||||
flag.Uint64Var(&Config.accessKeyCookieExpiry, "access-cookie-expiry", 0, "Expiration time for access key cookies in seconds (set 0 to use session cookies)")
|
flag.Uint64Var(&Config.accessKeyCookieExpiry, "access-cookie-expiry", 0, "Expiration time for access key cookies in seconds (set 0 to use session cookies)")
|
||||||
|
flag.StringVar(&Config.customPagesDir, "custompagespath", "",
|
||||||
|
"path to directory containing .md files to render as custom pages")
|
||||||
|
|
||||||
iniflags.Parse()
|
iniflags.Parse()
|
||||||
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 19 KiB |
|
@ -52,6 +52,7 @@ func populateTemplatesMap(tSet *pongo2.TemplateSet, tMap map[string]*pongo2.Temp
|
||||||
"404.html",
|
"404.html",
|
||||||
"oops.html",
|
"oops.html",
|
||||||
"access.html",
|
"access.html",
|
||||||
|
"custom_page.html",
|
||||||
|
|
||||||
"display/audio.html",
|
"display/audio.html",
|
||||||
"display/image.html",
|
"display/image.html",
|
||||||
|
@ -85,6 +86,8 @@ func renderTemplate(tpl *pongo2.Template, context pongo2.Context, r *http.Reques
|
||||||
|
|
||||||
context["sitepath"] = Config.sitePath
|
context["sitepath"] = Config.sitePath
|
||||||
context["selifpath"] = Config.selifPath
|
context["selifpath"] = Config.selifPath
|
||||||
|
context["custom_pages_names"] = customPagesNames
|
||||||
|
|
||||||
var a string
|
var a string
|
||||||
if Config.authFile == "" {
|
if Config.authFile == "" {
|
||||||
a = "none"
|
a = "none"
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}{{sitename}} - 404 Not Found{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="error-404">
|
<div class="error-404">
|
||||||
<a href="{{ sitepath }}"><img src='{{ sitepath }}static/images/404.jpg'></a>
|
<a href="{{ sitepath }}"><img src='{{ sitepath }}static/images/404.jpg'></a>
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}{{sitename}} - API{% endblock %}
|
||||||
|
|
||||||
{% block head %}
|
{% block head %}
|
||||||
<link href="{{ sitepath }}static/css/github-markdown.css" rel="stylesheet" type="text/css">
|
<link href="{{ sitepath }}static/css/github-markdown.css" rel="stylesheet" type="text/css">
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -12,47 +14,50 @@
|
||||||
<h2>API</h2>
|
<h2>API</h2>
|
||||||
|
|
||||||
<h3>Client</h3>
|
<h3>Client</h3>
|
||||||
<p>To simplify uploading and deleting files, you can use <a target="_blank" href="https://github.com/andreimarcu/linx-client">linx-client</a>, which uses this API.</p>
|
<p>To simplify uploading and deleting files, you can use <a target="_blank"
|
||||||
|
href="https://github.com/andreimarcu/linx-client">linx-client</a>, which uses this API.</p>
|
||||||
|
|
||||||
{% if auth != "none" %}
|
{% if auth != "none" %}
|
||||||
<h3>Keys</h3>
|
<h3>Keys</h3>
|
||||||
<p>This instance uses API Keys, therefore you will need to provide a key for uploading and deleting files.<br/> To do so, add the <code>Linx-Api-Key</code> header with your key.</p>
|
<p>This instance uses API Keys, therefore you will need to provide a key for uploading and deleting
|
||||||
|
files.<br /> To do so, add the <code>Linx-Api-Key</code> header with your key.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<h3>Uploading a file</h3>
|
<h3>Uploading a file</h3>
|
||||||
|
|
||||||
<p>To upload a file, make a PUT request to <code>{{ siteurl }}upload/</code> and you will get the url of your upload back.</p>
|
<p>To upload a file, make a PUT request to <code>{{ siteurl }}upload/</code> and you will get the url of
|
||||||
|
your upload back.</p>
|
||||||
|
|
||||||
<p><strong>Optional headers with the request</strong></p>
|
<p><strong>Optional headers with the request</strong></p>
|
||||||
|
|
||||||
{% if not forcerandom %}
|
{% if not forcerandom %}
|
||||||
<p>Randomize the filename<br/>
|
<p>Randomize the filename<br />
|
||||||
<code>Linx-Randomize: yes</code></p>
|
<code>Linx-Randomize: yes</code></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<p>Specify a custom deletion key<br/>
|
<p>Specify a custom deletion key<br />
|
||||||
<code>Linx-Delete-Key: mysecret</code></p>
|
<code>Linx-Delete-Key: mysecret</code></p>
|
||||||
|
|
||||||
<p>Protect file with password<br/>
|
<p>Protect file with password<br />
|
||||||
<code>Linx-Access-Key: mysecret</code></p>
|
<code>Linx-Access-Key: mysecret</code></p>
|
||||||
|
|
||||||
<p>Specify an expiration time (in seconds)<br/>
|
<p>Specify an expiration time (in seconds)<br />
|
||||||
<code>Linx-Expiry: 60</code></p>
|
<code>Linx-Expiry: 60</code></p>
|
||||||
|
|
||||||
<p>Get a json response<br/>
|
<p>Get a json response<br />
|
||||||
<code>Accept: application/json</code></p>
|
<code>Accept: application/json</code></p>
|
||||||
|
|
||||||
<p>The json response will then contain:</p>
|
<p>The json response will then contain:</p>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p>“url”: the publicly available upload url<br/>
|
<p>“url”: the publicly available upload url<br />
|
||||||
“direct_url”: the url to access the file directly<br/>
|
“direct_url”: the url to access the file directly<br />
|
||||||
“filename”: the (optionally generated) filename<br/>
|
“filename”: the (optionally generated) filename<br />
|
||||||
“delete_key”: the (optionally generated) deletion key,<br/>
|
“delete_key”: the (optionally generated) deletion key,<br />
|
||||||
“access_key”: the (optionally supplied) access key,<br/>
|
“access_key”: the (optionally supplied) access key,<br />
|
||||||
“expiry”: the unix timestamp at which the file will expire (0 if never)<br/>
|
“expiry”: the unix timestamp at which the file will expire (0 if never)<br />
|
||||||
“size”: the size in bytes of the file<br/>
|
“size”: the size in bytes of the file<br />
|
||||||
“mimetype”: the guessed mimetype of the file<br/>
|
“mimetype”: the guessed mimetype of the file<br />
|
||||||
“sha256sum”: the sha256sum of the file,</p>
|
“sha256sum”: the sha256sum of the file,</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
|
@ -92,7 +97,8 @@
|
||||||
|
|
||||||
<h3>Overwriting a file</h3>
|
<h3>Overwriting a file</h3>
|
||||||
|
|
||||||
<p>To overwrite a file you uploaded, simply provide the <code>Linx-Delete-Key</code> header with the original file's deletion key.</p>
|
<p>To overwrite a file you uploaded, simply provide the <code>Linx-Delete-Key</code> header with the
|
||||||
|
original file's deletion key.</p>
|
||||||
|
|
||||||
<p><strong>Example</p></strong>
|
<p><strong>Example</p></strong>
|
||||||
|
|
||||||
|
@ -108,7 +114,8 @@
|
||||||
|
|
||||||
<h3>Deleting a file</h3>
|
<h3>Deleting a file</h3>
|
||||||
|
|
||||||
<p>To delete a file you uploaded, make a DELETE request to <code>{{ siteurl }}yourfile.ext</code> with the delete key set as the <code>Linx-Delete-Key</code> header.</p>
|
<p>To delete a file you uploaded, make a DELETE request to <code>{{ siteurl }}yourfile.ext</code> with the
|
||||||
|
delete key set as the <code>Linx-Delete-Key</code> header.</p>
|
||||||
|
|
||||||
<p><strong>Example</strong></p>
|
<p><strong>Example</strong></p>
|
||||||
|
|
||||||
|
@ -124,15 +131,16 @@ DELETED</code></pre>
|
||||||
|
|
||||||
<h3>Information about a file</h3>
|
<h3>Information about a file</h3>
|
||||||
|
|
||||||
<p>To retrieve information about a file, make a GET request the public url with <code>Accept: application/json</code> headers and you will receive a json response containing:</p>
|
<p>To retrieve information about a file, make a GET request the public url with
|
||||||
|
<code>Accept: application/json</code> headers and you will receive a json response containing:</p>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p>“url”: the publicly available upload url<br/>
|
<p>“url”: the publicly available upload url<br />
|
||||||
“direct_url”: the url to access the file directly<br/>
|
“direct_url”: the url to access the file directly<br />
|
||||||
“filename”: the (optionally generated) filename<br/>
|
“filename”: the (optionally generated) filename<br />
|
||||||
“expiry”: the unix timestamp at which the file will expire (0 if never)<br/>
|
“expiry”: the unix timestamp at which the file will expire (0 if never)<br />
|
||||||
“size”: the size in bytes of the file<br/>
|
“size”: the size in bytes of the file<br />
|
||||||
“mimetype”: the guessed mimetype of the file<br/>
|
“mimetype”: the guessed mimetype of the file<br />
|
||||||
“sha256sum”: the sha256sum of the file,</p>
|
“sha256sum”: the sha256sum of the file,</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}{{sitename}} - Password protected file{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div id="main" class="oopscontent">
|
<div id="main" class="oopscontent">
|
||||||
<form action="{{ unlockpath }}" method="POST" enctype="multipart/form-data">
|
<form action="{{ unlockpath }}" method="POST" enctype="multipart/form-data">
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>{% block title %}{{ sitename }}{% endblock %}</title>
|
<title>{% block title %}{{ sitename }}{% endblock %}</title>
|
||||||
<meta charset='utf-8' content='text/html' http-equiv='content-type'>
|
<meta charset='utf-8' content='text/html' http-equiv='content-type'>
|
||||||
|
@ -20,6 +21,9 @@
|
||||||
<a href="{{ sitepath }}paste/">Paste</a> |
|
<a href="{{ sitepath }}paste/">Paste</a> |
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a href="{{ sitepath }}API/">API</a>
|
<a href="{{ sitepath }}API/">API</a>
|
||||||
|
{% for custom_file_name, custom_page_name in custom_pages_names sorted %}
|
||||||
|
| <a href="{{ sitepath }}{{ custom_file_name }}/">{{ custom_page_name }}</a>
|
||||||
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
<h2><a href="{{ sitepath }}" title="{{ sitename }}">{{ sitename }}</a></h2>
|
<h2><a href="{{ sitepath }}" title="{{ sitename }}">{{ sitename }}</a></h2>
|
||||||
</div>
|
</div>
|
||||||
|
@ -33,4 +37,5 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
|
@ -0,0 +1,19 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}{{sitename}} - {{ pagename }}{% endblock %}
|
||||||
|
|
||||||
|
{% block head %}
|
||||||
|
<link href="{{ sitepath }}static/css/github-markdown.css" rel="stylesheet" type="text/css">
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div id="main">
|
||||||
|
<div id='inner_content'>
|
||||||
|
<div class="normal markdown-body">
|
||||||
|
<h2>{{ pagename }}</h2>
|
||||||
|
|
||||||
|
{{ contents|safe }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -1,12 +1,12 @@
|
||||||
{% extends "../base.html" %}
|
{% extends "../base.html" %}
|
||||||
|
|
||||||
{% block title %}{{ filename }}{% endblock %}
|
{% block title %}{{sitename}} - {{ filename }}{% endblock %}
|
||||||
|
|
||||||
{% block bodymore %}{% endblock %}
|
{% block bodymore %}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div id="info" class="dinfo info-flex">
|
<div id="info" class="dinfo info-flex">
|
||||||
<div id="filename">
|
<div id="filename">
|
||||||
{{ filename }}
|
{{ filename }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -22,15 +22,15 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% block infoleft %}{% endblock %}
|
{% block infoleft %}{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="main" {% block mainmore %}{% endblock %}>
|
<div id="main" {% block mainmore %}{% endblock %}>
|
||||||
|
|
||||||
<div id='inner_content' {% block innercontentmore %}{% endblock %} >
|
<div id='inner_content' {% block innercontentmore %}{% endblock %}>
|
||||||
{% block main %}{% endblock %}
|
{% block main %}{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="{{ sitepath }}static/js/clipboard.js"></script>
|
<script src="{{ sitepath }}static/js/clipboard.js"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,21 +1,28 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}{{sitename}} - Paste{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form id="reply" action='{{ sitepath }}upload' method='post'>
|
<form id="reply" action='{{ sitepath }}upload' method='post'>
|
||||||
<div id="main" class="paste">
|
<div id="main" class="paste">
|
||||||
<div id="info" class="info-flex">
|
<div id="info" class="info-flex">
|
||||||
<div>
|
<div>
|
||||||
{% if not forcerandom %}<span class="hint--top hint--bounce" data-hint="Leave empty for random filename"><input class="codebox" name='filename' id="filename" type='text' value="" placeholder="filename" /></span>{% endif %}.<span class="hint--top hint--bounce" data-hint="Enable syntax highlighting by adding the extension"><input id="extension" class="codebox" name='extension' type='text' value="" placeholder="txt" /></span>
|
{% if not forcerandom %}<span class="hint--top hint--bounce"
|
||||||
|
data-hint="Leave empty for random filename"><input class="codebox" name='filename' id="filename"
|
||||||
|
type='text' value="" placeholder="filename" /></span>{% endif %}.<span
|
||||||
|
class="hint--top hint--bounce" data-hint="Enable syntax highlighting by adding the extension"><input
|
||||||
|
id="extension" class="codebox" name='extension' type='text' value="" placeholder="txt" /></span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span class="hint--top hint--bounce" data-hint="Require password to access (leave empty to disable)">
|
<span class="hint--top hint--bounce" data-hint="Require password to access (leave empty to disable)">
|
||||||
<input class="codebox" name="access_key" type="text" placeholder="password"/>
|
<input class="codebox" name="access_key" type="text" placeholder="password" />
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<select id="expiry" name="expires">
|
<select id="expiry" name="expires">
|
||||||
<option disabled>Expires:</option>
|
<option disabled>Expires:</option>
|
||||||
{% for expiry in expirylist %}
|
{% for expiry in expirylist %}
|
||||||
<option value="{{ expiry.Seconds }}"{% if forloop.Last %} selected{% endif %}>{{ expiry.Human }}</option>
|
<option value="{{ expiry.Seconds }}" {% if forloop.Last %} selected{% endif %}>{{ expiry.Human }}
|
||||||
|
</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
<button type="submit">Paste</button>
|
<button type="submit">Paste</button>
|
||||||
|
@ -26,7 +33,7 @@
|
||||||
<textarea name='content' id="content" class="editor"></textarea>
|
<textarea name='content' id="content" class="editor"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<script src="{{ sitepath }}static/js/util.js"></script>
|
<script src="{{ sitepath }}static/js/util.js"></script>
|
||||||
<script src="{{ sitepath }}static/js/paste.js"></script>
|
<script src="{{ sitepath }}static/js/paste.js"></script>
|
||||||
|
|
Loading…
Reference in New Issue