Skip to content

Commit

Permalink
feature: Added a convenient way to add attachments and wikilinks.
Browse files Browse the repository at this point in the history
As brought up in #128, a more convient way of adding links to existing
pages was missing in the editor. The right sidebar, which was the home
of un-convenient copy-n-paste markdown codes for attachments, has been
reworked: Now pages and attachments can be picked from a dropdown list
and inserted at the current cursor position in the editor.
  • Loading branch information
redimp committed Nov 16, 2024
1 parent fe05a2c commit fa34e02
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 47 deletions.
63 changes: 63 additions & 0 deletions otterwiki/static/js/otterwiki.js
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,69 @@ var otterwiki_editor = {
otterwiki_editor.table_arr_replace(arr, t.row, t.col);
cm_editor.focus();
},
update_attachment_preview: function() {
var element = document.getElementById("attachment-filename");
if (typeof(element) == 'undefined' || element == null) { return; }
// split value in filename, url and thumbnail_url
var filename = element.value.split("/--/")[0];
var url = element.value.split("/--/")[1];
var thumbnail_url = element.value.split("/--/")[2];
if (thumbnail_url == '') {
// empty preview box
document.getElementById("extranav-preview").innerHTML = "";
// update options
if (document.getElementById("attachment-link").checked != true)
{
document.getElementById("attachment-link").checked = true;
}
document.getElementById("attachment-image").disabled = true;
document.getElementById("attachment-thumbnail").disabled = true;
} else {
// image with thumbnail_url
// update preview box
var preview_img = document.createElement("img");
preview_img.setAttribute("src", thumbnail_url);
preview_img.setAttribute("alt", filename);
document.getElementById("extranav-preview").appendChild(preview_img);
// update options
document.getElementById("attachment-image").disabled = false;
document.getElementById("attachment-thumbnail").disabled = false;
}
},
insert_attachment: function() {
var element = document.getElementById("attachment-filename");
if (typeof(element) == 'undefined' || element == null) { return; }
// split value in filename, url and thumbnail_url
var filename = element.value.split("/--/")[0];
var url = element.value.split("/--/")[1];
var thumbnail_url = element.value.split("/--/")[2];
var attachment_type = document.querySelector("input[type='radio'][name=attachment-type]:checked").value;
if (typeof(attachment_type) == 'undefined' || attachment_type == null || attachment_type == '') { attachment_type = "link"; }
// handle relative and absolute paths
var attachment_absolute = document.getElementById("attachment-absolute").checked;
if (typeof(attachment_absolute) == 'undefined' || attachment_absolute == null || attachment_absolute == '') { attachment_absolute = false; }
if (!attachment_absolute) {
url = "./" + url.split("/").slice(-1)[0];
thumbnail_url = "./" + thumbnail_url.split("/").slice(-1)[0];
}

if (attachment_type == "image") {
otterwiki_editor.img('![]('+url+')\n');
} else if (attachment_type == "thumbnail") {
otterwiki_editor.img('[![]('+thumbnail_url+')]('+url+')\n');
} else { // link
otterwiki_editor.img('['+filename+']('+url+')\n');
}
// [![]({{f.thumbnail_url}})]({{f.url}})
},
insert_wikilink: function() {
var element = document.getElementById("wikilink");
if (typeof(element) == 'undefined' || element == null) { return; }
// split value in filename, url and thumbnail_url
var page = element.value.split("//")[0];
if (typeof(page) == 'undefined' || page == null || page == '') { return; }
otterwiki_editor.img('[['+page+']]\n');
}
}

var otterwiki = {
Expand Down
20 changes: 1 addition & 19 deletions otterwiki/templates/attachments.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
{{ super() }}
<meta name="robots" content="noindex, nofollow">
{% endblock %}
{% block extra_nav %}{% endblock %}
{% block content %}
<div class="w-full mw-full p-0 clearfix">
<h2 class="float-left">Attachments</h2>
Expand Down Expand Up @@ -47,25 +48,6 @@ <h2 class="float-left">Attachments</h2>
<tr class="align-top">
<td><a href="{{f.url}}">{% if f.thumbnail_url %}<img src="{{f.thumbnail_url}}"/>{%else%}{{f.thumbnail_icon|safe}}{%endif%}</a></td>
<td><a href="{{f.url}}">{{f.filename}}</a><br/>
{# copy n paste optionen #}
<div class="dropdown dropup">
<a href="#" data-toggle="dropdown" id="dropdown-toggle-btn-{{loop.index}}" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-copy"></i>
</a>
<div class="dropdown-menu" aria-labelledby="dropdown-toggle-btn-{{loop.index}}">
<h6 class="dropdown-header">Markdown Shortcuts <span class="font-size-12">- Click to copy to clipboard</span></h6>
{% if f.thumbnail_url %}
<a href="#" onclick="navigator.clipboard.writeText('![]({{f.url}})')" class="dropdown-item"><i class="fas fa-copy"></i> Inline Image:</a>
<div class="dropdown-item font-size-12">![]({{f.url}})</div>
<div class="dropdown-divider"></div>
<a href="#" onclick="navigator.clipboard.writeText('[![]({{f.thumbnail_url}})]({{f.url}})')" class="dropdown-item"><i class="fas fa-copy"></i> Link with Thumbnail:</a>
<div class="dropdown-item font-size-12>">[![]({{f.thumbnail_url}})]({{f.url}})</div>
<div class="dropdown-divider"></div>
{% endif %}
<a href="#" onclick="navigator.clipboard.writeText('[{{f.filename}}]({{f.url}})')" class="dropdown-item"><i class="fas fa-copy"></i> Link Attachment:</a>
<div class="dropdown-item font-size-12">[{{f.filename}}]({{f.url}})</div>
</div>
</div>
</td>
<td>{{f.filesize}}
<td>{{f.datetime|format_datetime}}<br/><span class="btn revision-small">{{f.revision}}</span></td>
Expand Down
70 changes: 42 additions & 28 deletions otterwiki/templates/editor.html
Original file line number Diff line number Diff line change
Expand Up @@ -188,34 +188,48 @@ <h5 class="modal-title">Save {{pagename}}</h5>
<div id="extranav-attachments">
<h5 class="sidebar-title"><a class="sidebar-title-link" href="{{ url_for('attachments', pagepath=pagepath ) }}">Attachments <i class="fa fa-paperclip"></i></a></h5>
<div class="sidebar-divider" ></div>
{% for f in files %}
{# <a href="{{f.url}}">{% if f.thumbnail_url %}<img src="{{f.thumbnail_url}}"/>{%else%}{{f.thumbnail_icon|safe}}{%endif%}</a>#}
<details class="collapse-panel pb-5">
<summary class="collapse-header font-size-12">
{{f.filename}}
</summary>
<div class="position-relative collapse-content font-size-12 extra-nav-attachment">
{% if f.thumbnail_url %}
<span class="font-weight-semi-bold">Inline Image:</span>
<a href="#" onclick="otterwiki_editor.img('![]({{f.url}})')" class="btn btn-xsm position-absolute" style="right: 3.5rem;"><i class="far fa-image"></i></a>
<a href="#" title="Copy to clipboard" onclick="navigator.clipboard.writeText('![]({{f.url}})')" class="btn btn-xsm position-absolute right-02"><i class="fas fa-copy"></i></a>
<div class="font-size-10 text-monospace py-5 break-all">![]({{f.url}})</div>
<!-- -->
<span class="font-weight-semi-bold">Link with Thumbnail:</span>
<a href="#" onclick="otterwiki_editor.img('[![]({{f.thumbnail_url}})]({{f.url}})')" class="btn btn-xsm position-absolute" style="right: 3.5rem;"><i class="far fa-image"></i></a>
<a href="#" onclick="navigator.clipboard.writeText('[![]({{f.thumbnail_url}})]({{f.url}})')" class="btn btn-xsm position-absolute right-02"><i class="fas fa-copy"></i></a>
<div class="font-size-10 text-monospace py-5 break-all">[![]({{f.thumbnail_url}})]({{f.url}})</div>
<!-- -->
{% endif %}
<span class="font-weight-semi-bold">Link:</span>
<a href="#" onclick="otterwiki_editor.img('[{{f.filename}}]({{f.url}})')" class="btn btn-xsm position-absolute" style="right: 3.5rem;"><i class="fas fa-link"></i></a>
<a href="#" onclick="navigator.clipboard.writeText('[{{f.filename}}]({{f.url}})')" class="btn btn-xsm position-absolute right-02"><i class="fas fa-copy"></i></a>
<div class="font-size-10 text-monospace py-5 break-all">[{{f.filename}}]({{f.url}})</div>
</div>
</details>
{% endfor %}
<p class="font-size-12 p-15 text-muted">Additional media can be added via the 'Attachments' of this page, or, you can drag and drop a file into the web editor and it will be uploaded and embedded when the page is saved.</p>
</div>
<form class="ml-10">
<select class="form-control" id="attachment-filename" onchange="otterwiki_editor.update_attachment_preview(this);">
<option value="" selected="selected" disabled="disabled">Select an attachment</option>
{% for f in files %}
<option value="{{f.filename}}/--/{{f.url}}/--/{{f.thumbnail_url or ''}}">{{f.filename}}</option>
{% endfor %}
</select>
<div id="extranav-preview" class="my-5"></div>
<div class="custom-radio mt-5 ml-5">
<input type="radio" name="attachment-type" id="attachment-link" value="link" checked="checked">
<label for="attachment-link">as link</label>
</div>
<div class="custom-radio mt-5 ml-5">
<input type="radio" name="attachment-type" id="attachment-image" value="image">
<label for="attachment-image">as image</label>
</div>
<div class="custom-radio mt-5 ml-5">
<input type="radio" name="attachment-type" id="attachment-thumbnail" value="thumbnail">
<label for="attachment-thumbnail">as link with thumbnail</label>
</div>
<div class="custom-checkbox mt-5 ml-5">
<input type="checkbox" id="attachment-absolute" value="checked">
<label for="attachment-absolute">use absolute path</label>
</div>
<button class="btn mt-5" type="button" onclick="otterwiki_editor.insert_attachment()" title="Copy into the editor" ><i class="fas fa-paste"></i></button>
</form>


<p class="font-size-12 p-15 text-muted">Additional media can be added via the 'Attachments' of this page, or, you can drag and drop a file into the web editor and it will be uploaded and embedded when the page is saved.</p>

<h5 class="sidebar-title">WikiLink <i class="fa fa-link"></i></h5>
<div class="sidebar-divider" ></div>
<form class="ml-10">
<select class="form-control" id="wikilink">
<option value="" selected="selected" disabled="disabled">Select an page to link</option>
{% for p in pages %}
<option value="{{p[1]}}">{{p[1]}}</option>
{% endfor %}
</select>
<button class="btn mt-5" type="button" onclick="otterwiki_editor.insert_wikilink()" title="Copy into the editor" ><i class="fas fa-paste"></i></button>
</form>
</div>
{{ super() }}
{%- endblock extra_nav %}
{#
Expand Down
10 changes: 10 additions & 0 deletions otterwiki/wiki.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
from timeit import default_timer as timer
from werkzeug.http import http_date
from werkzeug.utils import secure_filename
from urllib.parse import unquote
from io import BytesIO

import PIL.Image
Expand Down Expand Up @@ -221,6 +222,12 @@ def render(self):
breadcrumbs=self.breadcrumbs,
)

def pages(self):
for letter in self.toc:
for _, pagename, url, _, _ in self.toc[letter]:
pagepath = unquote(url)[1:]
yield pagename, pagepath, url


class Changelog:
def __init__(self, commit_start=None):
Expand Down Expand Up @@ -657,13 +664,16 @@ def editor(self, author, handle_draft=None):

# get file listing
files = [f.data for f in self._attachments() if f.metadata is not None]
# get page listing
page_idx = PageIndex()

return render_template(
"editor.html",
pagename=self.pagename,
pagepath=self.pagepath,
content_editor=content,
files=files,
pages=list(page_idx.pages()),
cursor_line=cursor_line,
cursor_ch=cursor_ch,
revision=(
Expand Down

0 comments on commit fa34e02

Please sign in to comment.