2
0
mirror of https://expo.survex.com/repositories/troggle/.git synced 2024-11-21 14:51:51 +00:00

Added some test pages showing different ways pages could be edited. This probably wants removing soon

This commit is contained in:
Martin Green 2022-06-28 00:18:24 +01:00
parent 82fe350493
commit 2af88353f3
6 changed files with 192 additions and 3 deletions

View File

@ -6,7 +6,7 @@ from django.forms import ModelForm
from django.forms.models import modelformset_factory
from django.contrib.admin.widgets import AdminDateWidget
#from tinymce.widgets import TinyMCE
from tinymce.widgets import TinyMCE
from troggle.core.models.troggle import Person, PersonExpedition, Expedition
from troggle.core.models.caves import Cave, LogbookEntry, QM, Entrance, CaveAndEntrance
@ -25,6 +25,7 @@ class CaveForm(ModelForm):
'''Only those fields for which we want to override defaults are listed here
the other fields are present on the form, but use the default presentation style
'''
official_name = forms.CharField(required = False, widget=forms.TextInput(attrs={'size': '45'}))
underground_description = forms.CharField(required = False, widget=HTMLarea(
attrs={"height":"80%", "rows":20, 'placeholder': "Enter page content (using HTML)"}))
@ -62,6 +63,123 @@ class CaveForm(ModelForm):
if self.cleaned_data.get("url") and self.cleaned_data.get("url").startswith("/"):
self._errors["url"] = self.error_class(["This field cannot start with a /."])
return self.cleaned_data
class CaveFormTextArea(ModelForm):
'''Only those fields for which we want to override defaults are listed here
the other fields are present on the form, but use the default presentation style
'''
official_name = forms.CharField(required = False, widget=forms.TextInput(attrs={'size': '45'}))
underground_description = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':9}))
explorers = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':9}))
equipment = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':9}))
survey = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':9}))
#survey = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 10}))
kataster_status = forms.CharField(required = False)
underground_centre_line = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':9}))
notes = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':9}))
references = forms.CharField(required = False, widget=forms.Textarea(attrs={'rows':9}))
description_file = forms.CharField(required = False, widget=forms.TextInput(attrs={'size': '45'}))
survex_file = forms.CharField(required = False, label="Survex file [caves-1623/000/000.svx]", widget=forms.TextInput(attrs={'size': '45'}))
url = forms.CharField(required = True, label="URL [1623/000/000]", widget=forms.TextInput(attrs={'size': '45'}))
length = forms.CharField(required = False, label="Length (m)")
depth = forms.CharField(required = False, label="Depth (m)")
extent = forms.CharField(required = False, label="Extent (m)")
class Meta:
model = Cave
exclude = ("filename",)
def clean(self):
if self.cleaned_data.get("kataster_number") == "" and self.cleaned_data.get("unofficial_number") == "":
self._errors["unofficial_number"] = self.error_class(["Either the kataster or unoffical number is required."])
# if self.cleaned_data.get("kataster_number") != "" and self.cleaned_data.get("official_name") == "":
# self._errors["official_name"] = self.error_class(["This field is required when there is a kataster number."])
if self.cleaned_data.get("area") == []:
self._errors["area"] = self.error_class(["This field is required."])
if self.cleaned_data.get("url") and self.cleaned_data.get("url").startswith("/"):
self._errors["url"] = self.error_class(["This field cannot start with a /."])
return self.cleaned_data
class CaveFormCodeMirrorPreview(ModelForm):
'''Only those fields for which we want to override defaults are listed here
the other fields are present on the form, but use the default presentation style
'''
official_name = forms.CharField(required = False, widget=forms.TextInput(attrs={'size': '45'}))
underground_description = forms.CharField(required = False, widget=HTMLarea(preview = True,
attrs={"height":"80%", "rows":20, 'placeholder': "Enter page content (using HTML)"}))
explorers = forms.CharField(required = False, widget=HTMLarea(preview = True,
attrs={"height":"80%", "rows":20, 'placeholder': "Enter page content (using HTML)"}))
equipment = forms.CharField(required = False, widget=HTMLarea(preview = True,
attrs={"height":"80%", "rows":20, 'placeholder': "Enter page content (using HTML)"}))
survey = forms.CharField(required = False, widget=HTMLarea(preview = True,
attrs={"height":"80%", "rows":20, 'placeholder': "Enter page content (using HTML)"}))
#survey = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 10}))
kataster_status = forms.CharField(required = False)
underground_centre_line = forms.CharField(required = False, widget=HTMLarea(preview = True,
attrs={"height":"80%", "rows":20, 'placeholder': "Enter page content (using HTML)"}))
notes = forms.CharField(required = False, widget=HTMLarea(preview = True,
attrs={"height":"80%", "rows":20, 'placeholder': "Enter page content (using HTML)"}))
references = forms.CharField(required = False, widget=HTMLarea(preview = True,
attrs={"height":"80%", "rows":20, 'placeholder': "Enter page content (using HTML)"}))
description_file = forms.CharField(required = False, widget=forms.TextInput(attrs={'size': '45'}))
survex_file = forms.CharField(required = False, label="Survex file [caves-1623/000/000.svx]", widget=forms.TextInput(attrs={'size': '45'}))
url = forms.CharField(required = True, label="URL [1623/000/000]", widget=forms.TextInput(attrs={'size': '45'}))
length = forms.CharField(required = False, label="Length (m)")
depth = forms.CharField(required = False, label="Depth (m)")
extent = forms.CharField(required = False, label="Extent (m)")
class Meta:
model = Cave
exclude = ("filename",)
def clean(self):
if self.cleaned_data.get("kataster_number") == "" and self.cleaned_data.get("unofficial_number") == "":
self._errors["unofficial_number"] = self.error_class(["Either the kataster or unoffical number is required."])
# if self.cleaned_data.get("kataster_number") != "" and self.cleaned_data.get("official_name") == "":
# self._errors["official_name"] = self.error_class(["This field is required when there is a kataster number."])
if self.cleaned_data.get("area") == []:
self._errors["area"] = self.error_class(["This field is required."])
if self.cleaned_data.get("url") and self.cleaned_data.get("url").startswith("/"):
self._errors["url"] = self.error_class(["This field cannot start with a /."])
return self.cleaned_data
class CaveFormTinyMCE(ModelForm):
'''Only those fields for which we want to override defaults are listed here
the other fields are present on the form, but use the default presentation style
'''
official_name = forms.CharField(required = False, widget=forms.TextInput(attrs={'size': '45'}))
underground_description = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 30}))
explorers = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 30}))
equipment = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 30}))
survey = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 30}))
#survey = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 10}))
kataster_status = forms.CharField(required = False)
underground_centre_line = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 30}))
notes = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 30}))
references = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 30}))
description_file = forms.CharField(required = False, widget=forms.TextInput(attrs={'size': '45'}))
survex_file = forms.CharField(required = False, label="Survex file [caves-1623/000/000.svx]", widget=forms.TextInput(attrs={'size': '45'}))
url = forms.CharField(required = True, label="URL [1623/000/000]", widget=forms.TextInput(attrs={'size': '45'}))
length = forms.CharField(required = False, label="Length (m)")
depth = forms.CharField(required = False, label="Depth (m)")
extent = forms.CharField(required = False, label="Extent (m)")
class Meta:
model = Cave
exclude = ("filename",)
def clean(self):
if self.cleaned_data.get("kataster_number") == "" and self.cleaned_data.get("unofficial_number") == "":
self._errors["unofficial_number"] = self.error_class(["Either the kataster or unoffical number is required."])
# if self.cleaned_data.get("kataster_number") != "" and self.cleaned_data.get("official_name") == "":
# self._errors["official_name"] = self.error_class(["This field is required when there is a kataster number."])
if self.cleaned_data.get("area") == []:
self._errors["area"] = self.error_class(["This field is required."])
if self.cleaned_data.get("url") and self.cleaned_data.get("url").startswith("/"):
self._errors["url"] = self.error_class(["This field cannot start with a /."])
return self.cleaned_data
class EntranceForm(ModelForm):
'''Only those fields for which we want to override defaults are listed here

View File

@ -18,7 +18,7 @@ import troggle.settings as settings
from troggle.core.views import expo
from troggle.core.models.troggle import Expedition, DataIssue
from troggle.core.models.caves import CaveSlug, Cave, CaveAndEntrance, QM, EntranceSlug, Entrance, Area, SurvexStation, GetCaveLookup
from troggle.core.forms import CaveForm, CaveAndEntranceFormSet, EntranceForm, EntranceLetterForm
from troggle.core.forms import CaveForm, CaveAndEntranceFormSet, EntranceForm, EntranceLetterForm, CaveFormCodeMirrorPreview, CaveFormTextArea, CaveFormTinyMCE
from .auth import login_required_if_public
'''Manages the complex procedures to assemble a cave description out of the compnoents
@ -297,6 +297,42 @@ def caveEntrance(request, slug):
else:
return render(request,'cave_entrances.html', {'cave': cave})
def test_edit_cave(request, editor = "codemirror"):
'''This is the form that edits all the cave data and writes out an XML file in the :expoweb: repo folder
The format for the file being saved is in templates/dataformat/cave.xml
It does save the data into into the database directly, not by parsing the file.
It does NOT yet commit to the git repoSaving is not allowed
'''
form_type = {"codemirror": CaveForm, "codemirrorpreview": CaveFormCodeMirrorPreview, "textarea": CaveFormTextArea, "tinymce": CaveFormTinyMCE}[editor]
message = ""
try:
cave = Cave.objects.get(caveslug__slug = "1623-264")
except:
return render(request,'errors/badslug.html')
if request.POST:
form = form_type(request.POST, instance=cave)
ceFormSet = CaveAndEntranceFormSet(request.POST)
#versionControlForm = VersionControlCommentForm(request.POST)
if form.is_valid() and ceFormSet.is_valid():
pass
else:
message = f'! POST data is INVALID {cave}'
print(message)
else:
form = form_type(instance=cave)
ceFormSet = CaveAndEntranceFormSet(queryset=cave.caveandentrance_set.all())
#versionControlForm = VersionControlCommentForm()
return render(request,
'editcave.html',
{'form': form, 'cave': cave, 'message': message,
'caveAndEntranceFormSet': ceFormSet,
'editor': editor,
#'versionControlForm': versionControlForm
})
@login_required_if_public
def edit_cave(request, slug=None):
'''This is the form that edits all the cave data and writes out an XML file in the :expoweb: repo folder
@ -305,6 +341,7 @@ def edit_cave(request, slug=None):
It does save the data into into the database directly, not by parsing the file.
It does NOT yet commit to the git repo
'''
message = ""
if slug is not None:
try:

View File

@ -14,3 +14,4 @@ reportlab==3.6.0
sqlparse==0.4.0
typing_extensions==4.2.0
Unidecode==1.3.0
django-tinymce

View File

@ -127,7 +127,26 @@ X_FRAME_OPTIONS = 'DENY' # changed to "DENY" after I eliminated all the iframes
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' # from Django 3.2
TINYMCE_JS_URL = 'https://cloud.tinymce.com/stable/tinymce.min.js'
TINYMCE_DEFAULT_CONFIG = {
"height": "320px",
"width": "960px",
"menubar": "file edit view insert format tools table help",
"plugins": "advlist autolink lists link image charmap print preview anchor searchreplace visualblocks code "
"fullscreen insertdatetime media table paste code help wordcount spellchecker",
"toolbar": "undo redo | bold italic underline strikethrough | fontselect fontsizeselect formatselect | alignleft "
"aligncenter alignright alignjustify | outdent indent | numlist bullist checklist | forecolor "
"backcolor casechange permanentpen formatpainter removeformat | pagebreak | charmap emoticons | "
"fullscreen preview save print | insertfile image media pageembed template link anchor codesample | "
"a11ycheck ltr rtl | showcomments addcomment code",
"custom_undo_redo_levels": 10,
"language": "es_ES", # To force a specific language instead of the Django current language.
}
TINYMCE_SPELLCHECKER = True
TINYMCE_COMPRESSOR = True
INSTALLED_APPS = (
'tinymce',
'django.contrib.admin',
'django.contrib.auth', # includes the url redirections for login, logout
'django.contrib.contenttypes',

View File

@ -2,6 +2,17 @@
{% block title %}Edit Cave - {{cave.official_name|safe}} - {{cave.kataster_number}}{% endblock %}
{% block extraheaders %}
{% include 'html_editor_scripts_css.html' %}
<script src="https://cdn.tiny.cloud/1/ib8fvyuhkhhdyt25zh35cbdo1gwvocm8w89e9vu3wf2107t4/tinymce/5/tinymce.min.js" referrerpolicy="origin"></script>
<script>
tinyMCE.init({
mode: "textareas",
plugins: "spellchecker,directionality,paste,searchreplace",
language: "{{ language }}",
directionality: "{{ directionality }}",
spellchecker_languages : "{{ spellchecker_languages }}",
spellchecker_rpc_url : "{{ spellchecker_rpc_url }}"
});
</script>
{% endblock %}
{% block content %}
<h1>Edit Cave - {{cave.official_name|safe}} - {{cave.kataster_number}}</h1>

View File

@ -13,7 +13,7 @@ from troggle.core.views.drawings import dwgallfiles, dwgfilesingle
from troggle.core.views.uploads import dwgupload, scanupload, photoupload
from troggle.core.views.other import troggle404, frontpage, todos, controlpanel, frontpage
from troggle.core.views.other import exportlogbook
from troggle.core.views.caves import ent, cavepage, caveindex, get_entrances, get_qms, edit_cave, cave3d, caveEntrance, edit_entrance, caveQMs, qm
from troggle.core.views.caves import ent, cavepage, caveindex, get_entrances, get_qms, edit_cave, cave3d, caveEntrance, edit_entrance, caveQMs, qm, test_edit_cave
from troggle.core.views.logbooks import get_logbook_entries, logbookentry, logbookSearch
from troggle.core.views.logbooks import notablepersons, person, get_people
from troggle.core.views.logbooks import expedition, personexpedition, Expeditions_tsvListView, Expeditions_jsonListView
@ -76,6 +76,8 @@ else:
# Some overlap with 'admin.site.urls' needs to be investigated.
trogglepatterns = [
path('tinymce/', include('tinymce.urls')),
path('expofiles/', include(expofilesurls)), # intercepted by Apache, if it is running.
path('expofiles', include(expofilesurls)), # curious interaction with the include() here, not just a slash problem.
@ -135,6 +137,7 @@ trogglepatterns = [
re_path(r'^(?P<karea>\d\d\d\d)(?P<subpath>.*)$', cavepage, name="cavepage"), # shorthand /1623/264 or 1623/161/top.htm
# Note that urls eg '/1623/161/l/rl89a.htm' are handled by cavepage which redirects them to 'expopage'
# Note that _edit$ for a cave description page in a subfolder e.g. /1623/204/204.html_edit gets caught here and breaks with 404
re_path(r'^test_cave_edit/(?P<editor>.*)$', test_edit_cave, name="test_edit_cave"), # edit_cave needed by cave.html template for url matching
# Entrances
re_path(r'^cave/entrance/([^/]+)/?$', caveEntrance), # lists all entrances !!!BAD, local links fail