summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/views/editor_helpers.py3
-rw-r--r--core/views/expo.py4
-rw-r--r--settings.py3
-rw-r--r--templates/editexpopage.html235
-rw-r--r--templates/html_editor_scripts_css.html166
-rw-r--r--templates/widgets/HTMLarea.html32
6 files changed, 210 insertions, 233 deletions
diff --git a/core/views/editor_helpers.py b/core/views/editor_helpers.py
index 1fe30b0..f85d582 100644
--- a/core/views/editor_helpers.py
+++ b/core/views/editor_helpers.py
@@ -130,3 +130,6 @@ class NewWebImageForm(forms.Form):
if full_path.exists():
raise forms.ValidationError("File already exists in %s" % rel_path)
return self.cleaned_data['file_']
+
+class HTMLarea(forms.Textarea):
+ template_name = "widgets/HTMLarea.html"
diff --git a/core/views/expo.py b/core/views/expo.py
index 91919a5..d84aa5f 100644
--- a/core/views/expo.py
+++ b/core/views/expo.py
@@ -23,6 +23,8 @@ import troggle.settings as settings
from troggle.lib import version_control
+from troggle.core.views.editor_helpers import HTMLarea
+
'''Formerly a separate package called 'flatpages' written by Martin Green 2011.
This was NOT django.contrib.flatpages which stores HTML in the database, so the name was changed to expopages.
@@ -380,5 +382,5 @@ class ExpoPageForm(forms.Form):
'''The form used by the editexpopage function
'''
title = forms.CharField(widget=forms.TextInput(attrs={'size':'60', 'placeholder': "Enter title (displayed in tab)"}))
- html = forms.CharField(widget=forms.Textarea(attrs={"cols":80, "rows":20, 'placeholder': "Enter page content (using HTML)"}))
+ html = forms.CharField(widget=HTMLarea(attrs={"cols":80, "rows":20, 'placeholder': "Enter page content (using HTML)"}))
change_message = forms.CharField(widget=forms.Textarea(attrs={"cols":80, "rows":3, 'placeholder': "Descibe the change made (for git)"}))
diff --git a/settings.py b/settings.py
index 7c05550..bcb972e 100644
--- a/settings.py
+++ b/settings.py
@@ -134,10 +134,13 @@ INSTALLED_APPS = (
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.admindocs',
+ 'django.forms', #Required to customise widget templates
# 'django.contrib.staticfiles', # We put our CSS etc explicitly in the right place so do not need this
'troggle.core',
)
+FORM_RENDERER = 'django.forms.renderers.TemplatesSetting' #Required to customise widget templates
+
# See the recommended order of these in https://docs.djangoproject.com/en/2.2/ref/middleware/
# Note that this is a radically different onion architecture from earlier versions though it looks the same,
# see https://docs.djangoproject.com/en/2.0/topics/http/middleware/#upgrading-pre-django-1-10-style-middleware
diff --git a/templates/editexpopage.html b/templates/editexpopage.html
index b71c91f..22c9106 100644
--- a/templates/editexpopage.html
+++ b/templates/editexpopage.html
@@ -2,243 +2,14 @@
{% block title %}Edit {{ path }}{% endblock %}
{% block extrahead %}
-<!--<script src="{{ settings.TINY_MCE_MEDIA_URL }}tiny_mce.js" type="text/javascript"></script>-->
-<!-- <script type="text/javascript"> tinyMCE.init({ mode : "textareas" }); </script>-->
-
-<script src="{{ settings.MEDIA_URL }}admin/js/vendor/jquery/jquery.js" type="text/javascript"></script>
-
- <script src={{ settings.MEDIA_URL }}codemirror/codemirror.js></script>
- <script src={{ settings.MEDIA_URL }}codemirror/xml.js></script>
- <script src={{ settings.MEDIA_URL }}codemirror/javascript.js></script>
- <script src={{ settings.MEDIA_URL }}codemirror/css.js></script>
- <script src={{ settings.MEDIA_URL }}codemirror/htmlmixed.js></script>
- <link rel=stylesheet href={{ settings.MEDIA_URL }}codemirror/codemirror.css>
- <link rel=stylesheet href={{ settings.MEDIA_URL }}codemirror/docs.css>
- <style type=text/css>
- .CodeMirror {
- float: left;
- width: 50%;
- border: 1px solid black;
- height: 80%;
- }
- .CodeMirror-scroll{
- height: 99%
- }
- iframe {
- width: 49%;
- height: 80%;
- float: left;
- border: 1px solid black;
- border-left: 0px;
- }
- body{max-width: none;
- margin-left: 275px;
- margin-right: 50px;
- text-align: left;
- }
- #id_change_message{
- height: 5%;
- }
- </style>
- <style type=text/css>
- html {
- font-family: "Helvetica Neue", sans-serif;
- width: 100%;
- color: #666666;
- text-align: center;
- }
-
- .popup-overlay {
- /*Hides pop-up when there is no "active" class*/
- visibility: hidden;
- position: absolute;
- background: #ffffff;
- border: 3px solid #666666;
- width: 90%;
- height: 80%;
- overflow: scroll;
- left: 5%;
- z-index: 20;
- }
-
- .popup-overlay.active {
- /*displays pop-up when "active" class is present*/
- visibility: visible;
- text-align: center;
- }
-
- .popup-content {
- /*Hides pop-up content when there is no "active" class */
- visibility: hidden;
- }
-
- .popup-content.active {
- /*Shows pop-up content when "active" class is present */
- visibility: visible;
- }
-
- button {
- display: inline-block;
- vertical-align: middle;
- border-radius: 30px;
- margin: .20rem;
- font-size: 1rem;
- color: #666666;
- background: #ffffff;
- border: 1px solid #666666;
- }
-
- button:hover {
- border: 1px solid #666666;
- background: #666666;
- color: #ffffff;
- }
- </style>
{% endblock %}
{% block body %}
<h1>Edit {{ path }}</h1>
-<!--Creates the add image popup-->
-<div class="add-image-popup popup-overlay">
- <div class="add-image-popup popup-content">
- <h2>Select Image</h2>
- <p id="image_popup_content"> Loading ...</p>
- <button onclick="new_image_popup()">Upload Image</button>
- <button class="close" onclick="$('.add-image-popup').removeClass('active');">Close</button>
- </div>
-</div>
-
-<!--Creates the new image popup-->
-<div class="new-image-popup popup-overlay">
- <div class="new-image-popup popup-content">
- <h2>New Image</h2>
- <p id="new_image_popup_content"> Loading ...</p>
- <button class="close" onclick="$('.new-image-popup').removeClass('active');">Close</button>
- </div>
-</div>
<form action="" method="post">{% csrf_token %}
-{{ form.non_field_errors }}
-<div class="fieldWrapper">
- {{ form.title.errors }}
- <label for="{{ form.title.id_for_label }}">Title:</label>
- {{ form.title }}
-</div>
-<div class="fieldWrapper">
- {{ form.html.errors }}
- <!--<label for="{{ form.title.id_for_label }}">HTML:</label> -->
- {{ form.html }}<iframe id=preview></iframe>
-</div>
-<button type="button" onclick="addTag('i', '')">italic</button>
-<button type="button" onclick="addTag('b', '')">bold</button>
-<button type="button" onclick="addTag('h2', 'id=&quot;tophead&quot;')">top heading</button>
-<button type="button" onclick="addTag('h1', '')">heading 1</button>
-<button type="button" onclick="addTag('h2', '')">heading 2</button>
-<button type="button" onclick="addTag('h3', '')">heading 3</button>
-<button type="button" onclick="addTag('h4', '')">heading 4</button>
-<button type="button" onclick="addTag('a', 'href=&quot;&quot;')">hyperlink</button>
-<button type="button" onclick="addTag('p', '')">paragraph</button>
-<button type="button" onclick="add_image_popup()">image</button>
-<div class="fieldWrapper">
- {{ form.change_message.errors }}
- <label for="{{ form.title.id_for_label }}">Git change message:</label>
- {{ form.change_message }}
-</div>
-{% include "menu.html" %}
+{{ form.as_p }}
<p><input type="submit" value="Submit" /></p>
</form>
-
-
-<script>
-
-
-function add_image_popup() {
- $('.add-image-popup').addClass('active');
- $('#image_popup_content').load("{% url 'image_selector' path %}", function() {
- $('.thumbnail').click(function(){
- $(".add-image-popup").removeClass("active");
- addStr($( this ).attr("data-html"))
- });
- })
- }
-function new_image_popup() {
- $('.add-image-popup').removeClass('active');
- $('.new-image-popup').addClass('active');
- $.ajax({
- type : "GET",
- dataType: "json",
- url: "{% url 'new_image_form' path %}",
- success: function(data){handle_new_image(data)}
- });
- }
-
-function handle_new_image(data) {
- if (data.hasOwnProperty('form')) {
- $('#new_image_popup_content').html(data.form);
- $('#new_image_form').on('submit', function(e){
- e.preventDefault();
- data = $('#new_image_form').serialize();
-
- $.ajax({
- type : "POST",
- dataType: "json",
- url: "{% url 'new_image_form' path %}",
- data: new FormData($('#new_image_form')[0]),
- processData: false,
- contentType: false,
- success: function(data){
- handle_new_image(data);
- }
- });
- });
- }
- else if (data.hasOwnProperty('html')) {
- $('.new-image-popup').removeClass('active');
- addStr(data.html);
- }
- else {
- alert(data.error);
- }
- }
-</script>
- <script>
- var delay;
- // Initialize CodeMirror editor with a nice html5 canvas demo.
- var editor = CodeMirror.fromTextArea(document.getElementById('id_html'), {
- mode: 'text/html',
- tabMode: 'indent',
- onChange: function() {
- clearTimeout(delay);
- delay = setTimeout(updatePreview, 300);
- }
- });
-
- function updatePreview() {
- var previewFrame = document.getElementById('preview');
- var preview = previewFrame.contentDocument || previewFrame.contentWindow.document;
- preview.open();
- preview.write("<html><head><meta http-equiv='Content-Type' content='text/html; charset=utf-8' /><link rel='stylesheet' type='text/css' href='/css/main2.css' /> <style type=text/css>body{max-width: none;margin-left: 15px;margin-right: 15px;}</style></head><body>");
- preview.write(editor.getValue());
- preview.write("</body></html>");
- preview.close();
- }
- setTimeout(updatePreview, 300);
-
- function addTag(tag, attr){
- // For codemirror & center cursor
- var from = editor.getCursor(true);
- var to = editor.getCursor(false);
- editor.replaceRange("</"+tag+">", to);
- if (attr.length > 0) {attr = " " + attr;}
- editor.replaceRange("<"+tag+attr+">", from);
- editor.focus();
- editor.setCursor({line: to.line , ch : to.ch + 2 + tag.length + attr.length });
- }
-
- function addStr(x){
- var to = editor.getCursor(false);
- editor.replaceRange(x, to);
- editor.focus();
- editor.setCursor({line: to.line , ch : to.ch + x.length });
- }
- </script>
+{% include "menu.html" %}
+{% include 'html_editor_scripts_css.html' %}
{% endblock %}
diff --git a/templates/html_editor_scripts_css.html b/templates/html_editor_scripts_css.html
new file mode 100644
index 0000000..5bd56d4
--- /dev/null
+++ b/templates/html_editor_scripts_css.html
@@ -0,0 +1,166 @@
+<script src="{{ settings.MEDIA_URL }}admin/js/vendor/jquery/jquery.js" type="text/javascript"></script>
+
+ <script src={{ settings.MEDIA_URL }}codemirror/codemirror.js></script>
+ <script src={{ settings.MEDIA_URL }}codemirror/xml.js></script>
+ <script src={{ settings.MEDIA_URL }}codemirror/javascript.js></script>
+ <script src={{ settings.MEDIA_URL }}codemirror/css.js></script>
+ <script src={{ settings.MEDIA_URL }}codemirror/htmlmixed.js></script>
+ <link rel=stylesheet href={{ settings.MEDIA_URL }}codemirror/codemirror.css>
+ <link rel=stylesheet href={{ settings.MEDIA_URL }}codemirror/docs.css>
+ <style type=text/css>
+ .CodeMirror {
+ float: left;
+ width: 50%;
+ border: 1px solid black;
+ height: 80%;
+ }
+ .CodeMirror-scroll{
+ height: 99%
+ }
+ iframe {
+ width: 49%;
+ height: 80%;
+ float: left;
+ border: 1px solid black;
+ border-left: 0px;
+ }
+ body{max-width: none;
+ margin-left: 275px;
+ margin-right: 50px;
+ text-align: left;
+ }
+ #id_change_message{
+ height: 5%;
+ }
+ </style>
+ <style type=text/css>
+ html {
+ font-family: "Helvetica Neue", sans-serif;
+ width: 100%;
+ color: #666666;
+ text-align: center;
+ }
+
+ .popup-overlay {
+ /*Hides pop-up when there is no "active" class*/
+ visibility: hidden;
+ position: absolute;
+ background: #ffffff;
+ border: 3px solid #666666;
+ width: 90%;
+ height: 80%;
+ overflow: scroll;
+ left: 5%;
+ z-index: 20;
+ }
+
+ .popup-overlay.active {
+ /*displays pop-up when "active" class is present*/
+ visibility: visible;
+ text-align: center;
+ }
+
+ .popup-content {
+ /*Hides pop-up content when there is no "active" class */
+ visibility: hidden;
+ }
+
+ .popup-content.active {
+ /*Shows pop-up content when "active" class is present */
+ visibility: visible;
+ }
+
+
+ </style>
+<script>
+function add_image_popup() {
+ $('.add-image-popup').addClass('active');
+ $('#image_popup_content').load("{% url 'image_selector' path %}", function() {
+ $('.thumbnail').click(function(){
+ $(".add-image-popup").removeClass("active");
+ addStr($( this ).attr("data-html"))
+ });
+ })
+ }
+function new_image_popup() {
+ $('.add-image-popup').removeClass('active');
+ $('.new-image-popup').addClass('active');
+ $.ajax({
+ type : "GET",
+ dataType: "json",
+ url: "{% url 'new_image_form' path %}",
+ success: function(data){handle_new_image(data)}
+ });
+ }
+
+function handle_new_image(data) {
+ if (data.hasOwnProperty('form')) {
+ $('#new_image_popup_content').html(data.form);
+ $('#new_image_form').on('submit', function(e){
+ e.preventDefault();
+ data = $('#new_image_form').serialize();
+
+ $.ajax({
+ type : "POST",
+ dataType: "json",
+ url: "{% url 'new_image_form' path %}",
+ data: new FormData($('#new_image_form')[0]),
+ processData: false,
+ contentType: false,
+ success: function(data){
+ handle_new_image(data);
+ }
+ });
+ });
+ }
+ else if (data.hasOwnProperty('html')) {
+ $('.new-image-popup').removeClass('active');
+ addStr(data.html);
+ }
+ else {
+ alert(data.error);
+ }
+ }
+</script>
+ <script>
+ var delay;
+ // Initialize CodeMirror editor with a nice html5 canvas demo.
+ var editor = CodeMirror.fromTextArea(document.getElementById('id_html'), {
+ mode: 'text/html',
+ tabMode: 'indent',
+ onChange: function() {
+ clearTimeout(delay);
+ delay = setTimeout(updatePreview, 300);
+ }
+ });
+
+ function updatePreview() {
+ var previewFrame = document.getElementById('preview');
+ var preview = previewFrame.contentDocument || previewFrame.contentWindow.document;
+ preview.open();
+ preview.write("<html><head><meta http-equiv='Content-Type' content='text/html; charset=utf-8' /><link rel='stylesheet' type='text/css' href='/css/main2.css' /> <style type=text/css>body{max-width: none;margin-left: 15px;margin-right: 15px;}</style></head><body>");
+ preview.write(editor.getValue());
+ preview.write("</body></html>");
+ preview.close();
+ }
+ setTimeout(updatePreview, 300);
+
+ function addTag(tag, attr){
+ // For codemirror & center cursor
+ var from = editor.getCursor(true);
+ var to = editor.getCursor(false);
+ editor.replaceRange("</"+tag+">", to);
+ if (attr.length > 0) {attr = " " + attr;}
+ editor.replaceRange("<"+tag+attr+">", from);
+ editor.focus();
+ editor.setCursor({line: to.line , ch : to.ch + 2 + tag.length + attr.length });
+ }
+
+ function addStr(x){
+ var to = editor.getCursor(false);
+ editor.replaceRange(x, to);
+ editor.focus();
+ editor.setCursor({line: to.line , ch : to.ch + x.length });
+ }
+ </script>
+
diff --git a/templates/widgets/HTMLarea.html b/templates/widgets/HTMLarea.html
new file mode 100644
index 0000000..9837327
--- /dev/null
+++ b/templates/widgets/HTMLarea.html
@@ -0,0 +1,32 @@
+<!--Creates the add image popup-->
+<div><div class="add-image-popup popup-overlay">
+ <div class="add-image-popup popup-content">
+ <h2>Select Image</h2>
+ <p id="image_popup_content"> Loading ...</p>
+ <button onclick="new_image_popup()">Upload Image</button>
+ <button class="close" onclick="$('.add-image-popup').removeClass('active');">Close</button>
+ </div>
+</div>
+
+<!--Creates the new image popup-->
+<div class="new-image-popup popup-overlay">
+ <div class="new-image-popup popup-content">
+ <h2>New Image</h2>
+ <p id="new_image_popup_content"> Loading ...</p>
+ <button class="close" onclick="$('.new-image-popup').removeClass('active');">Close</button>
+ </div>
+</div>
+{% include "django/forms/widgets/textarea.html" %}
+<iframe id=preview></iframe>
+<button type="button" onclick="addTag('i', '')">italic</button>
+<button type="button" onclick="addTag('b', '')">bold</button>
+<button type="button" onclick="addTag('h2', 'id=&quot;tophead&quot;')">top heading</button>
+<button type="button" onclick="addTag('h1', '')">heading 1</button>
+<button type="button" onclick="addTag('h2', '')">heading 2</button>
+<button type="button" onclick="addTag('h3', '')">heading 3</button>
+<button type="button" onclick="addTag('h4', '')">heading 4</button>
+<button type="button" onclick="addTag('a', 'href=&quot;&quot;')">hyperlink</button>
+<button type="button" onclick="addTag('p', '')">paragraph</button>
+<button type="button" onclick="add_image_popup()">image</button>
+<button type="button" onclick="addStr('<hr/>')">horizontal line</button>
+</div>