Implementation example
Added example and changed default configuration to use this example by default to be used out of the box.
This commit is contained in:
parent
87685c4a62
commit
3f7d06fc0f
21
__implementation_example/README.md
Normal file
21
__implementation_example/README.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# How to use this example
|
||||||
|
|
||||||
|
Please run
|
||||||
|
|
||||||
|
`hugo --bind dev.localhost --baseURL http://dev.localhost --disableLiveReload`
|
||||||
|
|
||||||
|
in this folder to view this example. Point your web browser then to
|
||||||
|
[dev.localhost](http://dev.localhost:1313).
|
||||||
|
|
||||||
|
Please also add
|
||||||
|
|
||||||
|
`127.0.0.1 dev.localhost`
|
||||||
|
|
||||||
|
to
|
||||||
|
|
||||||
|
* Windows: `C:\windows\system32\drivers\etc\hosts`
|
||||||
|
* MAC/Linux: `/etc/hosts`
|
||||||
|
|
||||||
|
before running the example.
|
||||||
|
|
||||||
|
**There is another readme when you view the page.**
|
6
__implementation_example/archetypes/default.md
Normal file
6
__implementation_example/archetypes/default.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
title: "{{ replace .Name "-" " " | title }}"
|
||||||
|
date: {{ .Date }}
|
||||||
|
draft: true
|
||||||
|
---
|
||||||
|
|
4
__implementation_example/config.toml
Normal file
4
__implementation_example/config.toml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
baseURL = "http://dev.localhost/"
|
||||||
|
languageCode = "en-us"
|
||||||
|
disableKinds = ["taxonomy", "term"]
|
||||||
|
ignoreErrors = ["error-disable-taxonomy"]
|
94
__implementation_example/content/blog/readme.md
Normal file
94
__implementation_example/content/blog/readme.md
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
---
|
||||||
|
title: "Labertasche minimal implementation example"
|
||||||
|
date: 2020-12-03 09:00:00
|
||||||
|
categories: blog
|
||||||
|
---
|
||||||
|
|
||||||
|
This is a minimal example on how to implement Labertasche,
|
||||||
|
using Bulma CSS. The CSS is not that important, however, it
|
||||||
|
also shows how to utilize a modal dialogue to give your users
|
||||||
|
a good experience.
|
||||||
|
|
||||||
|
<!--more-->
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
Please modify `mail_credentials.yaml` and make sure mail can be sent.
|
||||||
|
Everything else is set up. You can run flask with pycharm or on a local
|
||||||
|
server. It is up to you. I recommend using pycharm with the flask parameters
|
||||||
|
`--host=dev.localhost --port=1314`. Make sure `dev.localhost` is in your
|
||||||
|
hosts file and resolves to `127.0.0.1`. This is necessary to set a cookie domain.
|
||||||
|
The server will not be able to run without.
|
||||||
|
|
||||||
|
## Where to start?
|
||||||
|
|
||||||
|
Start by reading `layouts/_default/baseof.html`. Notice the Javascript.
|
||||||
|
It has the default `labertasche.js` included and a custom file, where I
|
||||||
|
handle the callbacks. In production, you would concat these files using
|
||||||
|
the Hugo asset pipeline. I've left them separate, so you can see what is custom and what is included.
|
||||||
|
|
||||||
|
The next stop should be `single.html`. There you can find the first go block
|
||||||
|
needed, which adds the comments to each article in Hugo. Query for sections
|
||||||
|
if you want to exclude certain sections or only allow one, e.g. `blog`.
|
||||||
|
|
||||||
|
Last but not least, `comments.html` in the partials folder. This is where
|
||||||
|
basically all the magic happens. Read the javascript functions as they appear.
|
||||||
|
Basically, all I am doing is to query the DOM elements and adding/removing
|
||||||
|
classes as I go, to display certain things. There is also a quick explanation further down.
|
||||||
|
|
||||||
|
**Please note**: This version has a modified reply function, so it displays the
|
||||||
|
hidden field with the reply id.
|
||||||
|
This does not occur on the production version, but can be helpful for debugging.
|
||||||
|
|
||||||
|
## Javascript functions explained
|
||||||
|
|
||||||
|
This is a quick and short explanation of all javascript functions. Yes, you may use and modify them.
|
||||||
|
|
||||||
|
### labertasche_text_counter()
|
||||||
|
|
||||||
|
This function counts the amount of characters put into the text area. This is purely cosmetic and only the first
|
||||||
|
filter. If users have disabled Javascript, they could circumvent this, so the server checks lengths too.
|
||||||
|
|
||||||
|
### labertasche_validate_mail()
|
||||||
|
|
||||||
|
This checks if the entered text is a valid mail address, with a regex match. This does not check if the
|
||||||
|
domain exists or if the mail is _really_ an email, but that is done server side. It's only used to minimize false
|
||||||
|
requests.
|
||||||
|
|
||||||
|
### labertasche_modal_hide()
|
||||||
|
|
||||||
|
This hides the modal dialog when the button on the modal is clicked.
|
||||||
|
|
||||||
|
### labertasche_comment_not_found()
|
||||||
|
|
||||||
|
When a comment is not valid, Labertasche will redirect to `dev.localhost?cnf=true`. This function shows a modal
|
||||||
|
to inform the user about it. The JS for checking this parameter is in `baseof.html`.
|
||||||
|
|
||||||
|
### labertasche_comment_deleted()
|
||||||
|
|
||||||
|
Same as above, but with `dev.localhost?deleted=true`. This happens when a user deletes the comment via the link
|
||||||
|
sent by mail.
|
||||||
|
|
||||||
|
### labertasche_post_callback(state)
|
||||||
|
|
||||||
|
This is the callback used via the Labertasche post function. It simply displays different modals when certain error
|
||||||
|
codes are received. This is extremely useful, because you can inform your user about what is happening.
|
||||||
|
|
||||||
|
### labertasche_reply_callback(state, comment_id)
|
||||||
|
|
||||||
|
The callback for the reply callback. This does a little more, it displays a new button which the user can press to
|
||||||
|
disable the reply and go to a parent comment. This is useful, because the user does not have to reload the site and
|
||||||
|
therefore, does not need to type it all again, if the reply was done in error.
|
||||||
|
|
||||||
|
## Feedback
|
||||||
|
|
||||||
|
Hope this example makes it more comfortable to use Labertasche, please send me a mail or open an issue if anything
|
||||||
|
is unclear.
|
||||||
|
|
||||||
|
## Try it out!
|
||||||
|
|
||||||
|
Scroll down and comment. This is only locally. Please note: If livereload is enabled, you may not see all dialogs.
|
||||||
|
Turn livereload in Hugo off, if you want to see all of them:
|
||||||
|
`--disableLiveReload`.
|
||||||
|
|
||||||
|
The example comments also will disappear when you comment, as they are not included in the database.
|
61
__implementation_example/content/blog/stramine.md
Normal file
61
__implementation_example/content/blog/stramine.md
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
---
|
||||||
|
title: "Stramine ad coniugiale hi Procne"
|
||||||
|
date: 2020-12-04 08:00:00
|
||||||
|
categories: blog
|
||||||
|
---
|
||||||
|
|
||||||
|
## Qui velox repperit
|
||||||
|
|
||||||
|
Lorem markdownum spatio animas animorum Scyrumve Noctis gramine, fata, sit
|
||||||
|
cives, cui mea. Abesto Thesea coniecit, in rictus *quem pedis caret* tutaeque
|
||||||
|
sacra.
|
||||||
|
|
||||||
|
1. Urit deae freto nubifer oculi
|
||||||
|
2. Ferrumque dilata quaeque
|
||||||
|
3. Mihi luminis color tandem mirum quodque
|
||||||
|
|
||||||
|
<!--more-->
|
||||||
|
|
||||||
|
## Videt accipiunt habet
|
||||||
|
|
||||||
|
Potest rapto: nata honores, primos, laudamus scrutantur in. Similis incursurus
|
||||||
|
enim inritata postes, est caelo, sis *nondum*, spumantiaque licet tenens
|
||||||
|
conbibitur excutis levis. Spargit dedere laetissimus liquidi, ad mergit, lintea
|
||||||
|
*armis erunt esse* aratri, sideraque piceis.
|
||||||
|
|
||||||
|
Gestare petentes saevo multoque, ad *esset inhibere* omnibus, iter de Dixerat
|
||||||
|
dira. Illi mora sed altera ferrum tibi, qui ignis aris nocti quatiens est.
|
||||||
|
|
||||||
|
## Amplexus stantes paciscor tot unum
|
||||||
|
|
||||||
|
Amens fugit membra flabat gemellam et Venus **protinus**. Gyaros esse tibi exhausta. Nulla sed
|
||||||
|
numina linguae plura, prosiluit tamen, inscius, cui Phoebus circumspexit
|
||||||
|
spatiumque **indigenae caecaque**.
|
||||||
|
|
||||||
|
if (server + san < w(ospf, webMemory, speed_column +
|
||||||
|
sli_vaporware_definition)) {
|
||||||
|
kernelBarFile = archieSmishing;
|
||||||
|
base_png_click(rte_warm, dongle);
|
||||||
|
}
|
||||||
|
var midi = addressP.router(reader.koffice(dslClickKeylogger(rpm, 2,
|
||||||
|
dataRom), 5));
|
||||||
|
cd_media = koffice.dos.shortcut(3, html_boot.horizontal_trash_extension(
|
||||||
|
subdirectory)) - tunneling(login, camelcase_cursor_opacity(
|
||||||
|
flash_graphic, soap, serp_e_debug));
|
||||||
|
sdk_lte_software(5);
|
||||||
|
|
||||||
|
## Attollit unde fingens
|
||||||
|
|
||||||
|
Longeque frangunt, spectant temptavit, reperta invito, tectis face vos mirabile
|
||||||
|
Cycladas. Reliquit voverat, quattuor imago utinam crudelem rapta, nomina ullos
|
||||||
|
latuit resurgere. Terraque vitae.
|
||||||
|
|
||||||
|
1. Senex et ipse esse cruentior caluere
|
||||||
|
2. Sub quae
|
||||||
|
3. Ubi sunt sedens cladis certamine maior hiscere
|
||||||
|
|
||||||
|
Aequantibus admota; cuncta sit quod fugias dextra certaminis oro ecce auditis
|
||||||
|
pater. Fluunt herbas si est. Animam precesque esse gradumque videndo vultum,
|
||||||
|
lapides, fera **corpora temperat**, adnuit fortis. Se et Ceycis; ille tergo
|
||||||
|
frondes hospitibus quoque et? Dixit inposuit in cetera pinus triplices convicia;
|
||||||
|
rupit intus suorum, et?
|
22
__implementation_example/data/blog/readme.json
Normal file
22
__implementation_example/data/blog/readme.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"comments": [
|
||||||
|
{
|
||||||
|
"comment_id": 1,
|
||||||
|
"email": "commenter1@",
|
||||||
|
"content": "This is an example comment with over 40 characters.",
|
||||||
|
"created_on": "2020-12-04 12:23:14",
|
||||||
|
"replied_to": null,
|
||||||
|
"gravatar": "d9eef4df0ae5bfc1a9a9b1e39a99c07f"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"replies": [
|
||||||
|
{
|
||||||
|
"comment_id": 2,
|
||||||
|
"email": "commenter2@",
|
||||||
|
"content": "This is an example reply, to test if this works.",
|
||||||
|
"created_on": "2020-12-04 12:24:19",
|
||||||
|
"replied_to": 1,
|
||||||
|
"gravatar": "d9eef4df0ae5bfc1a9a9b1e39a99c07f"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
22
__implementation_example/data/blog/stramine.json
Normal file
22
__implementation_example/data/blog/stramine.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"comments": [
|
||||||
|
{
|
||||||
|
"comment_id": 1,
|
||||||
|
"email": "commenter1@",
|
||||||
|
"content": "This is an example comment with over 40 characters.",
|
||||||
|
"created_on": "2020-12-04 12:23:14",
|
||||||
|
"replied_to": null,
|
||||||
|
"gravatar": "d9eef4df0ae5bfc1a9a9b1e39a99c07f"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"replies": [
|
||||||
|
{
|
||||||
|
"comment_id": 2,
|
||||||
|
"email": "commenter2@",
|
||||||
|
"content": "This is an example reply, to test if this works.",
|
||||||
|
"created_on": "2020-12-04 12:24:19",
|
||||||
|
"replied_to": 1,
|
||||||
|
"gravatar": "d9eef4df0ae5bfc1a9a9b1e39a99c07f"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
56
__implementation_example/layouts/_default/baseof.html
Normal file
56
__implementation_example/layouts/_default/baseof.html
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, user-scalable=yes">
|
||||||
|
<link rel="stylesheet" href="/css/labertasche.css" media="screen">
|
||||||
|
<title>Labertasche Example</title>
|
||||||
|
</head>
|
||||||
|
<body class="is-family-sans-serif bg-darkslate">
|
||||||
|
<section>
|
||||||
|
<nav class="navbar" role="navigation" aria-label="main navigation">
|
||||||
|
<a class="navbar-item is-size-4" href="/">
|
||||||
|
Labertasche Example
|
||||||
|
</a>
|
||||||
|
<div class="navbar-start"></div>
|
||||||
|
<div class="navbar-end"></div>
|
||||||
|
</nav>
|
||||||
|
<div class="p-4">
|
||||||
|
{{ block "main" . }}
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<script defer src="/js/labertasche.js"></script>
|
||||||
|
<script defer src="/js/mysite.js"></script>
|
||||||
|
<script defer>
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
// Comments
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
if (urlParams.get("cnf") === "true"){
|
||||||
|
labertasche_comment_not_found();
|
||||||
|
}
|
||||||
|
if (urlParams.get("deleted") === "true"){
|
||||||
|
labertasche_comment_deleted();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<!-- Modal for notifications -->
|
||||||
|
<div class="modal" id="labertasche-modal">
|
||||||
|
<div class="modal-background"></div>
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="content p-5 mb-0 is-rounded bg-yayellow has-text-black">
|
||||||
|
<p class="title">Labertasche</p>
|
||||||
|
</div>
|
||||||
|
<div class="content p-5 mb-0 bg-deepmatte has-text-white" id="labertasche-modal-text">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="content p-5 bg-deepmatte has-text-white border-top">
|
||||||
|
<button onclick="labertasche_modal_hide();" class="button is-warning" aria-label="close">
|
||||||
|
OK
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button onclick="labertasche_modal_hide();" class="modal-close is-large" aria-label="close"></button>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,7 @@
|
|||||||
|
{{ block "frontpage_article" . }}
|
||||||
|
<article class="p-3 bg-deepmatte brdr-yayellow">
|
||||||
|
<p class="title has-text-white">{{ .Title }}</p>
|
||||||
|
<p>{{ .Summary }}</p>
|
||||||
|
<p><a href="{{.RelPermalink}}">Read the whole article...</a></p>
|
||||||
|
</article>
|
||||||
|
{{ end }}
|
12
__implementation_example/layouts/_default/home.html
Normal file
12
__implementation_example/layouts/_default/home.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{{ define "main" }}
|
||||||
|
<div class="container">
|
||||||
|
<div class="content">
|
||||||
|
{{ $last_article := (.Site.GetPage "blog" .Section).Pages.ByPublishDate }}
|
||||||
|
{{ range last 2 $last_article }}
|
||||||
|
<div class="mt-4">
|
||||||
|
{{ .Render "frontpage_article" }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
13
__implementation_example/layouts/_default/single.html
Normal file
13
__implementation_example/layouts/_default/single.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{{ define "main" }}
|
||||||
|
<article class="container p-3 bg-deepmatte brdr-yayellow">
|
||||||
|
<p class="title has-text-white">{{ .Title }}</p>
|
||||||
|
<div class="content has-text-justified has-text-white">{{ .Content }}</div>
|
||||||
|
</article>
|
||||||
|
<article class="container p-3 bg-deepmatte brdr-yayellow mt-5">
|
||||||
|
<div>
|
||||||
|
{{ $file := replaceRE "^(.*)[\\/]$" "data$1.json" .Page.RelPermalink }}
|
||||||
|
{{ .Scratch.Set "location" $file }}
|
||||||
|
{{ partial "partials/comments" . }}
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
{{ end }}
|
108
__implementation_example/layouts/partials/comments.html
Normal file
108
__implementation_example/layouts/partials/comments.html
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
{{ $location := .Scratch.Get "location" }}
|
||||||
|
<!--suppress XmlDuplicatedId -->
|
||||||
|
<h1 class="is-uppercase has-text-white">comments</h1>
|
||||||
|
|
||||||
|
<div class="mb-5" id="labertasche-comment-section" data-remote="http://dev.localhost:1314/comments/new">
|
||||||
|
<div class="control is-expanded">
|
||||||
|
<input onkeypress="labertasche_validate_mail();"
|
||||||
|
onfocusout="labertasche_validate_mail();"
|
||||||
|
maxlength="100"
|
||||||
|
id="labertasche-mail"
|
||||||
|
class="input"
|
||||||
|
type="email"
|
||||||
|
placeholder="joedoe@example.com">
|
||||||
|
</div>
|
||||||
|
<div class="control is-expanded mt-3">
|
||||||
|
<textarea oninput="labertasche_text_counter();"
|
||||||
|
id="labertasche-text"
|
||||||
|
class="textarea"
|
||||||
|
rows="5"
|
||||||
|
maxlength="1000"
|
||||||
|
placeholder="40 minimum characters, type something nice..."></textarea>
|
||||||
|
<p id="labertasche-text-helper"
|
||||||
|
class="help is-danger">Characters: <span id="labertasche-counter">0/1000</span></p>
|
||||||
|
</div>
|
||||||
|
<div class="control mt-3">
|
||||||
|
<button onclick="labertasche_post_comment(this, labertasche_post_callback);"
|
||||||
|
class="button is-warning px-6 mr-4 is-medium"
|
||||||
|
id="labertasche-comment-button">
|
||||||
|
<span>Comment</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<article>
|
||||||
|
<div class="media mb-5 brdr-yayellow my-shadow-subtle bg-compliment">
|
||||||
|
<figure class="media-left ml-0 mb-0">
|
||||||
|
<p class="image is-128x128">
|
||||||
|
<img alt="gravatar portrait" src="/images/default.jpg">
|
||||||
|
</p>
|
||||||
|
</figure>
|
||||||
|
<div class="media-content">
|
||||||
|
<div class="content mr-5 mt-2 has-text-left">
|
||||||
|
Pinned by <span class="fg-yellow">admin@example.com</span>
|
||||||
|
<br><br>
|
||||||
|
<span class="mt-5 has-text-justified">
|
||||||
|
<span>
|
||||||
|
Come join the discussion and write something nice. You will have to confirm your comment by mail,
|
||||||
|
so make sure it is legit and not a throwaway. Only the name part of it will be displayed, so
|
||||||
|
don't worry about spam.
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
{{ if (fileExists $location ) }}
|
||||||
|
{{ $dataJ := getJSON $location }}
|
||||||
|
{{ range $dataJ.comments }}
|
||||||
|
<article>
|
||||||
|
<div class="media mb-5 brdr-yayellow my-shadow-subtle bg-compliment">
|
||||||
|
<figure class="media-left ml-0 mb-0">
|
||||||
|
<p class="image is-128x128">
|
||||||
|
<img alt="gravatar portrait" src="https://www.gravatar.com/avatar/{{.gravatar}}.jpg">
|
||||||
|
</p>
|
||||||
|
</figure>
|
||||||
|
<div class="media-content">
|
||||||
|
<div class="content mr-5 mt-2">
|
||||||
|
<a id="comment_{{.comment_id}}" href="#comment_{{.comment_id}}">#{{.comment_id}}</a>
|
||||||
|
Posted by <span class="fg-yellow">{{.email}}</span> <small>on {{.created_on}}</small>
|
||||||
|
<br><br>
|
||||||
|
<span class="mt-5">
|
||||||
|
{{.content}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="is-fullwidth bg-yayellow has-text-centered">
|
||||||
|
<a class="has-text-black" href="#labertasche-comment-section"
|
||||||
|
onclick="labertasche_reply_to({{.comment_id}}, labertasche_reply_callback);">
|
||||||
|
reply
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
{{ range where $dataJ.replies "replied_to" .comment_id }}
|
||||||
|
<article>
|
||||||
|
<div class="media margin-left-128 mb-5 brdr-yayellow my-shadow-subtle bg-compliment">
|
||||||
|
<figure class="media-left ml-0 mb-0">
|
||||||
|
<p class="image is-128x128">
|
||||||
|
<img alt="gravatar portrait" src="https://www.gravatar.com/avatar/{{.gravatar}}.jpg">
|
||||||
|
</p>
|
||||||
|
</figure>
|
||||||
|
<div class="media-content">
|
||||||
|
<div class="content mr-5 mt-2">
|
||||||
|
<a id="comment_{{.comment_id}}" href="#comment_{{.comment_id}}">#{{.comment_id}}</a>
|
||||||
|
Posted by <span class="fg-yellow">{{.email}}</span> <small>on {{.created_on}}
|
||||||
|
</small>
|
||||||
|
<br><br>
|
||||||
|
<span class="mt-5">
|
||||||
|
{{.content}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
{{end}}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
12
__implementation_example/static/css/labertasche.css
Normal file
12
__implementation_example/static/css/labertasche.css
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
169
__implementation_example/static/css/tuxstash.css.map
Normal file
169
__implementation_example/static/css/tuxstash.css.map
Normal file
File diff suppressed because one or more lines are too long
BIN
__implementation_example/static/images/default.jpg
Normal file
BIN
__implementation_example/static/images/default.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
After Width: | Height: | Size: 8.5 KiB |
122
__implementation_example/static/js/labertasche.js
Normal file
122
__implementation_example/static/js/labertasche.js
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
//**********************************************************************************
|
||||||
|
// * _author : Domeniko Gentner
|
||||||
|
// * _mail : code@tuxstash.de
|
||||||
|
// * _repo : https://git.tuxstash.de/gothseidank/labertasche
|
||||||
|
// * _license : This project is under MIT License
|
||||||
|
// *********************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
//Callback example for post. Possible messages:
|
||||||
|
// post-min-length
|
||||||
|
// post-max-length
|
||||||
|
// post-invalid-json
|
||||||
|
// post-duplicate
|
||||||
|
// post-internal-server-error
|
||||||
|
// post-success
|
||||||
|
// post-before-fetch
|
||||||
|
function labertasche_callback(state)
|
||||||
|
{
|
||||||
|
if (state === "post-before-fetch"){
|
||||||
|
|
||||||
|
}
|
||||||
|
if (state === "post-min-length"){
|
||||||
|
|
||||||
|
}
|
||||||
|
if (state === "post-success"){
|
||||||
|
|
||||||
|
}
|
||||||
|
if (state === "post-fetch-exception" || state === "post-internal-server-error"){
|
||||||
|
|
||||||
|
}
|
||||||
|
if (state === "post-invalid-email"){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback for initiating and cancelling replies.
|
||||||
|
// Posstible message: 'on' and 'off'
|
||||||
|
function labertasche_reply_callback()
|
||||||
|
{
|
||||||
|
if (state === "on"){
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state === "off"){
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
function labertasche_reply_to(comment_id, callback)
|
||||||
|
{
|
||||||
|
let comments = document.getElementById('labertasche-comment-section');
|
||||||
|
if (comments){
|
||||||
|
if (document.getElementById('labertasche-replied-to')){
|
||||||
|
document.getElementById('labertasche-replied-to').remove();
|
||||||
|
callback('off', comment_id);
|
||||||
|
if (comment_id === -1){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let reply = document.createElement("input");
|
||||||
|
reply.setAttribute("type", "text");
|
||||||
|
reply.setAttribute("id", "labertasche-replied-to");
|
||||||
|
//reply.classList.add("is-hidden");
|
||||||
|
reply.value = comment_id;
|
||||||
|
comments.appendChild(reply);
|
||||||
|
callback('on', comment_id);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
console.log("Missing text input with id labertasche-comment-section");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function labertasche_post_comment(btn, callback)
|
||||||
|
{
|
||||||
|
let remote = document.getElementById('labertasche-comment-section').dataset.remote;
|
||||||
|
let comment = document.getElementById('labertasche-text').value.trim();
|
||||||
|
let mail = document.getElementById('labertasche-mail').value.trim();
|
||||||
|
let reply = document.getElementById('labertasche-replied-to');
|
||||||
|
|
||||||
|
if (mail.length <= 0 || comment.length < 40){
|
||||||
|
callback('post-min-length');
|
||||||
|
if(btn) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let reply_value = null
|
||||||
|
if (reply != null){
|
||||||
|
reply_value = reply.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback('post-before-fetch');
|
||||||
|
fetch(remote,
|
||||||
|
{
|
||||||
|
mode:"cors",
|
||||||
|
headers: {
|
||||||
|
'Access-Control-Allow-Origin':'*',
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
method: "POST",
|
||||||
|
// use real location
|
||||||
|
body: JSON.stringify({ "email": mail,
|
||||||
|
"content": comment,
|
||||||
|
"location": window.location.pathname,
|
||||||
|
"replied_to": reply_value
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(async function(response){
|
||||||
|
let result = await response.json();
|
||||||
|
callback(result['status']);
|
||||||
|
})
|
||||||
|
.catch(function(exc){
|
||||||
|
console.log(exc);
|
||||||
|
callback('post-fetch-exception');
|
||||||
|
})
|
||||||
|
|
||||||
|
// Don't reload the page
|
||||||
|
return false;
|
||||||
|
}
|
138
__implementation_example/static/js/mysite.js
Normal file
138
__implementation_example/static/js/mysite.js
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
|
||||||
|
|
||||||
|
function labertasche_text_counter()
|
||||||
|
{
|
||||||
|
let txt = document.getElementById('labertasche-text');
|
||||||
|
let cntr = document.getElementById('labertasche-counter');
|
||||||
|
let maxlen = txt.getAttribute("maxlength");
|
||||||
|
let helper = document.getElementById("labertasche-text-helper");
|
||||||
|
if (cntr && txt){
|
||||||
|
cntr.innerText = txt.value.length + "/" + maxlen;
|
||||||
|
if (txt.value.length > 40){
|
||||||
|
if (helper.classList.contains('is-danger')){
|
||||||
|
helper.classList.remove("is-danger");
|
||||||
|
helper.classList.add("is-success");
|
||||||
|
txt.classList.add('is-success');
|
||||||
|
txt.classList.remove('is-danger');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (txt.value.length < 40){
|
||||||
|
if (helper.classList.contains('is-success')){
|
||||||
|
helper.classList.remove("is-success");
|
||||||
|
helper.classList.add("is-danger");
|
||||||
|
txt.classList.add('is-danger');
|
||||||
|
txt.classList.remove('is-success');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function labertasche_validate_mail()
|
||||||
|
{
|
||||||
|
let email = document.getElementById("labertasche-mail");
|
||||||
|
let is_valid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.value);
|
||||||
|
if (is_valid){
|
||||||
|
email.classList.remove("is-danger")
|
||||||
|
email.classList.add("is-success")
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
email.classList.add("is-danger")
|
||||||
|
email.classList.remove("is-success")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function labertasche_modal_hide()
|
||||||
|
{
|
||||||
|
let modal = document.getElementById('labertasche-modal');
|
||||||
|
if (modal != null){
|
||||||
|
if (modal.classList.contains("is-active")){
|
||||||
|
modal.classList.remove('is-active');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function labertasche_comment_not_found()
|
||||||
|
{
|
||||||
|
let modal = document.getElementById('labertasche-modal');
|
||||||
|
let modal_text = document.getElementById('labertasche-modal-text');
|
||||||
|
modal_text.innerText = "The link you followed was not valid. It either doesn't exist or was already used.";
|
||||||
|
modal.classList.add('is-active');
|
||||||
|
}
|
||||||
|
|
||||||
|
function labertasche_comment_deleted()
|
||||||
|
{
|
||||||
|
let modal = document.getElementById('labertasche-modal');
|
||||||
|
let modal_text = document.getElementById('labertasche-modal-text');
|
||||||
|
modal_text.innerText = "Your comment has been deleted. Thank you for being here.";
|
||||||
|
modal.classList.add('is-active');
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
post-min-length
|
||||||
|
post-max-length
|
||||||
|
post-invalid-json
|
||||||
|
post-duplicate
|
||||||
|
post-internal-server-error
|
||||||
|
post-success
|
||||||
|
post-before-fetch
|
||||||
|
*/
|
||||||
|
function labertasche_post_callback(state)
|
||||||
|
{
|
||||||
|
// Elements
|
||||||
|
let modal = document.getElementById('labertasche-modal');
|
||||||
|
let modal_text = document.getElementById('labertasche-modal-text');
|
||||||
|
let button = document.getElementById('labertasche-comment-button');
|
||||||
|
|
||||||
|
if (state === "post-before-fetch"){
|
||||||
|
button.classList.add("is-loading");
|
||||||
|
}
|
||||||
|
if (state === "post-min-length"){
|
||||||
|
button.classList.remove("is-loading");
|
||||||
|
modal_text.innerText = "Your comment was not entered because it is too short. Please write at least 40 characters."
|
||||||
|
modal.classList.add('is-active');
|
||||||
|
}
|
||||||
|
if (state === "post-success"){
|
||||||
|
button.classList.remove("is-loading");
|
||||||
|
modal_text.innerText = "Your comment was entered, but you need to confirm it, before it becomes active. Please check your mail!"
|
||||||
|
modal.classList.add('is-active');
|
||||||
|
}
|
||||||
|
if (state === "post-fetch-exception" || state === "post-internal-server-error"){
|
||||||
|
button.classList.remove("is-loading");
|
||||||
|
modal_text.innerText = "Your comment was not entered because there was an error, which was recorded and reported automatically.";
|
||||||
|
modal.classList.add('is-active');
|
||||||
|
}
|
||||||
|
if (state === "post-invalid-email"){
|
||||||
|
button.classList.remove("is-loading");
|
||||||
|
modal_text.innerText = "The email you have entered appears to be invalid. Please contact me if you think this was in error.";
|
||||||
|
modal.classList.add('is-active');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function labertasche_reply_callback(state, comment_id)
|
||||||
|
{
|
||||||
|
if (state === "on"){
|
||||||
|
let comment_btn = document.getElementById('labertasche-comment-button');
|
||||||
|
let parent = comment_btn.parentElement
|
||||||
|
let new_btn = document.createElement("button");
|
||||||
|
new_btn.classList.add("button");
|
||||||
|
new_btn.classList.add("is-danger");
|
||||||
|
new_btn.classList.add("is-medium");
|
||||||
|
new_btn.classList.add("px-6");
|
||||||
|
new_btn.setAttribute("id", "labertasche-cancel-reply");
|
||||||
|
new_btn.onclick = function() { labertasche_reply_to(-1, labertasche_reply_callback); }
|
||||||
|
new_btn.innerHTML = '<span>Cancel Reply</span>';
|
||||||
|
parent.appendChild(new_btn);
|
||||||
|
|
||||||
|
comment_btn.innerHTML = "<span class='is-medium'>Reply to #" + comment_id + "</span>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state === "off"){
|
||||||
|
console.log("off");
|
||||||
|
let comment_btn = document.getElementById('labertasche-comment-button');
|
||||||
|
comment_btn.innerHTML = "<span class='is-medium'>Comment</span>";
|
||||||
|
let cancel = document.getElementById('labertasche-cancel-reply');
|
||||||
|
if (cancel){
|
||||||
|
cancel.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,20 +6,21 @@
|
|||||||
# *********************************************************************************/
|
# *********************************************************************************/
|
||||||
|
|
||||||
system:
|
system:
|
||||||
web_url: "http://comments.example.com" # Url where the comment system is served
|
web_url: "http://dev.localhost:1314/" # Url where the comment system is served
|
||||||
blog_url: "http://myblog.example.com" # Url of your website
|
blog_url: "http://dev.localhost:1313/" # Url of your website
|
||||||
cookie-domain: "dev.localhost" # Url where the comment system is served
|
cookie-domain: "dev.localhost" # Url where the comment system is served
|
||||||
database_uri: "sqlite:///db/labertasche.db" # Database URI. Default is sqlite.
|
database_uri: "sqlite:///db/labertasche.db" # Database URI. See documentation. Default is sqlite.
|
||||||
secret: "123456" # CHANGE ME! THIS IS IMPORTANT!
|
secret: "6Gxvb52bIJCm2vfDsmWKzShKp1omrzVG" # CHANGE ME! THIS IS IMPORTANT!
|
||||||
output: "/path/to/hugo_dir/data" # Base path for the output json
|
output: "./__implementation_example/data/" # Base path for the output json
|
||||||
debug: false # Leave this as is, this is for development.
|
debug: false # Leave this as is, this is for development.
|
||||||
send_otp_to_publish: true # Disables confirmation w/ OTP via mail
|
send_otp_to_publish: true # Disables confirmation w/ OTP via mail
|
||||||
|
|
||||||
gravatar:
|
gravatar:
|
||||||
cache: true # Enable caching of gravatar images
|
cache: true # Enable caching of gravatar images
|
||||||
static_dir: "/path/to/hugo_dir//static/images/gravatar/" # Where to store cached images
|
static_dir: "./__implementation_example/static/images/gravatar/" # Where to store cached images, must exist!
|
||||||
size: 256 # only applies if images are cached,
|
size: 256 # only applies if images are cached,
|
||||||
# otherwise use ?s=size at the end of the gravatar url
|
# otherwise use ?s=size at the end of the gravatar url
|
||||||
|
|
||||||
dashboard:
|
dashboard:
|
||||||
username: "admin" # CHANGE ME!
|
username: "admin" # CHANGE ME!
|
||||||
password: "admin" # CHANGE ME!
|
password: "admin" # CHANGE ME!
|
||||||
@ -29,7 +30,7 @@ addons:
|
|||||||
|
|
||||||
# If you want to expand this, please use this list:
|
# If you want to expand this, please use this list:
|
||||||
# https://www.w3schools.com/charsets/ref_emoji_smileys.asp
|
# https://www.w3schools.com/charsets/ref_emoji_smileys.asp
|
||||||
# You need to both versions, upper and lowercase, if you want both to works
|
# You need to add upper and lowercase, if you want both to work.
|
||||||
# This is a simple search and replace action
|
# This is a simple search and replace action
|
||||||
smileys:
|
smileys:
|
||||||
":)": "😀"
|
":)": "😀"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user