Allowing users to edit page content in Django website - django

I have a Django-powered site that's like a mini CMS. I want to let users with no HTML knowledge edit the contents of the page. The problem is that most of the pages have some more or less complex HTML bits in them (for example a Bootstrap accordion), which needs to be intact for the page to not break.
I tried setting up an WYSIWYG editor, but that turned out to be a disaster, because it heavily alters my HTML (removes attributes, adds p tags all over etc).
Is there a viable option to let people change the text of the page, but not the HTML structure?
For reference, my Page model looks like:
class Page(models.Model):
title = models.CharField(max_length=150)
content = models.TextField()

Have you tried django-content-edit (https://pypi.org/project/django-content-edit/) by David Burke.
Basically you then create HTML part of your pages and add CMS_CONTENT -tags to different places. Editing content is done using WYSIWYG -control in Django admin, where available features (links, images, styles, ...) can be limited using configurations. That gives you pretty good control of everything.
It has it's own problems, like it easily messes up HTML stuff you have added in RAW view, because it automatically opens content in WYSIWYG view, which seems to remove HTML tags it does not understand/support. It also doesn't work YET with Django 2.0, because on_delete is now mandatory for ForeignKey and OneToOneField model fields.
I know this is very old question, but I answered anyway.

Related

Sitecore 9 - Add an Image to a Link in the Footer

A client is using Sitecore 9 - we are not Sitecore developers.
We've been asked a simple thing: add social media links to the Footer of their Sitecore site.
Its proving more difficult than expected.
I've added the links on other pages by editing the HTML directly via the WYSWIG editor.
But the Footer appears more restricted, only accepting the addition of templates like 'Link'.
The 'Link' template has an option to add an external URL but doesn't have an option to add an image.
The CMS looks like this:
Is there any way to add a link, with an image, via the CMS (without the need to write Sitecore code), so the page chnages from this:
to this:
If you dont want to write Sitecore code, maybe you should think about using frontend.
Find the views that holds the footer (probably Foundation/Footer.cshtml) or something like that.
-To easily find where it is, follow these steps
Go to a content page Presentation Details that has footer (probably any)
Go to Controls
Find the footer rendering in there
Click on it
Grab the Datasource's value
Go to the Datasource's path
There should be a field holding the value of the view.
Add some css class on the div that holds those items, and do your frontend stuff in there...
It is not a scalable solution, so I would highly recommend updating the Footer rendering by adding new fields and adapting the model/view. So that way a content editor could easily add a new value for each socials.

Django: displaying all fields of all tables, the dumbest view possible

I've inherited a Django PostGres application with a model containing around 40 tables.
I've redesigned the model from head to toe, and now I'm setting in to re-build the web front end. I haven't used Django previous to this project - and no HTML for many years - but I'm happy enough with the ORM end of Django.
As a raw default, I just wanted to display all the fields of a class on an individual html page. Any references (i.e. ForeignKeys, or ManyToOne references) should appear as html links to another html page, which displays that class' data.
The application that I've inherited does more or less that, but uses about 50 modules containing hundreds of boiler-plate views, forms, and serializers - absolutely none of which contain anything remotely intelligent in. The "active" code on each form just sayd 'all'.
Rather than autogenerate this code (yuk!), is there a quick way of asking Django to display a basic tabular view unless there is a bespoke view for the table?

django - how to make clickable html text that sends data to model?

I want to display users around 10 clickable html "tags" (just text with some css that changes when clicked) on my form page. I want them to be able to select a maximum of 3 tags but no minimum requirement. I then want to take the sum of all clicks for each individual tag and do some calculations with them as a model method, like return the 3 most clicked tags.
It's important that my tags are on the form page and are submitted at the same time as the form. So I guess they have to be part of my form.
How would I go about doing this? An actual example would be tremendously helpful as I'm still very new to django and find the documentation (which I've looked at) somewhat hard to understand.
If you know the tags ahead of time, I'd recommend this setup:
Use a multiple select widget in your form (see the favorite_colors field in this Django widgets example)
Use Select2 or another JavaScript library that converts <select multiple> inputs into a tags-like UI
If you go that route, this widget from django-select2 looks like it should get you off to the races.

Editable unstructured pages

I'm building a small site framework for a set of sites that are likely to have quite a few unstructured pages - meaning they have:
Slightly different layouts per page
Lots of one-off text
None/very little generated content from models
I would like to allow clients to edit the content of these pages through my admin UI (I'm using Django for this project), but with the requirement that they are not exposed to the page HTML and are only able to edit parts of the page that I've specified as fields; for example:
Titles
A few blocks of text content
Perhaps some blocks of predefined image locations
PDF files that need embedding
Where these fields vary significantly between pages.
The layout, and what fields these pages require would be specified by the developer, so there's no need to dynamically generate much for this.
The 'best' idea I've had so far is to serialise these blocks of content once they've been edited by the user and store them in a 'Pages' table/model in my relational database, or just throw MongoDB or similar at it.
Conceptually, how would you implement such pages? As mentioned, I'm using Django so any implementation suggestions specific to Django are welcome, but general high-level ideas would be great too.
I would implement a ContentBlock model, which has .kind (header, text, image, pdf) and a .data, which would house the content (if text) or path to an uploaded pdf/image/etc. Presumably then you'd hardcode the pages with the appropriate blocks defined - I'd just use hardcoded slugs, eg, 'home-title', 'home-intro', 'about-title', 'about-text', 'about-right-photo', etc.
I would suggest not using Django's admin interface. It's much more suited to editing homogenous, non-business-logic models. I'd just add an edit view that renders the appropriate form fields for the blocks instead - html editor, file upload, etc. It's possible to do that in the django admin, but in my experience it's not worth the trouble - plus, if you do your own edit view, you can have it use the same base templates as the rest of the site, which IMO is a better user experience.
Here are a couple of apps which do that for you:
django-generic-flatblocks
django-boxes
Along with django-frontendadmin, it's super cool.

How to access page title in Django templates?

How can I get the page title in the template? I know there are ways to do this with javascript, but I'll prefer a template-tag or a variable if it exists.
The page title is an html element (<title>Title Here</title>), and django has no idea what that is.
Django's templates render the raw HTML text, which a browser parses and only then does the concept of a page title exist for javascript to parse.
If you need it in django, you'd want to ensure django is building that title tag and you would access it in the same way you'd display any other variable in a template.
It's probably best left to the DOM tools since a title might be created in any number of ways. If you absolutely need it in django, I would probably parse the final rendered HTML with an HTML parser like BeautifulSoup.
title = BeautifulSoup(mytemplate.render(Context({}))).html.head.title