Django CMS simple placeholders outside of cms - python

I have a fully developed Django app and decided to add DjangoCMS to give a content developers a quick way to prototype landing pages etc. It now lives under myurl.com/cms and works quite well. The guys can create new pages, choose a template and add plugins there.
When i saw the placeholder template tag I immediately thought about placing it all over the project, outside the cms, everywhere I want the product team to be able to quickly add and change content. I don't want them to create a new page for this from the cms because maybe the site has complex functionality which is only used once in this context (i.e. the search page).
So basically I expect to have static placeholders that I can place in the html part of the page using the cms plugins template tags.
I already found Placeholders outside the CMS in the DjangoCMS docs.
But for this to work I have to grab the related placeholder object for every view that renders a page, which would increase the amount of work to "quickly add a placeholder for this text" considerably.
Is there an easy way to do this? I kind of expect to not be the first to have that issue.

There's three types of placeholders:
Page placeholders - Declared using {% placeholder %}. These can only be used inside a cms page.
Static placeholders - Declared using {% static_placeholder %}. Not bound to pages or objects.
App placeholder - Declared in your models.py using PlaceholderField and rendered in template using {% render_placeholder %}
The rule of thumb is, if you're rendering a cms page, use a page placeholder, otherwise depending on your use-case use a static placeholder.

Related

Define multiple templates for a predefined block wagtail CRX

I was moving a site over to wagtail and decided to use the codered extensions. The library comes with a image-gallery content-block. I want to use this but define a few templates you can choose from in the admin UI.
You usually define a template in the meta section, but I noticed a dropdown in the admin UI for a template.
How do I add a template to that dropdown? Link to the content block I want to change
I am interested in adding an HTML template and not inheriting from the content-block to change behaviour. (Unless inheriting is the only way to add a template to the dropdown.)
You could paramatise the path to the template you want to use then use an include in your block template to point to the chosen one.
For example, if you had a card block with selection for vertical or horizontal format. In your card block class you might have an property named template that uses a choice block, something like
class AlignmentChoiceBlock(ChoiceBlock):
choices=[
('blocks/flex/vertical_card.html', 'Vertical'),
('blocks/flex/horizontal_card.html', 'Horizontal')
]
Then in your block template, it just consists of:
<div class="some-block-container">
{% include value.template %}
</div>
Well, this works for Wagtail at least, not sure about codered.
The answer from Richard Allen works wagtail and is perfect for your own blocks etc. Wagtail blocks define a separate field that is used for their included components, for this you need another approach.
First you need to add the CRX_FRONTEND_TEMPLATE_BLOCKS to your django settings mysite/settings/base.py.
Then create a folder for your block templates in mysite/website/templates and create a custom template. Then add this path as a entry to the CRX_FRONTEND_TEMPLATE_BLOCKS. Entry key should be the block in lowercase. For a starter you could copy a template/html file from the codered package, found in coderedcms/blocks/
Now the template should be available from the template dropdown under the advanced menu of a crx block.
This info came from a gh issue of crx. This is e pretty recent addition and the dev mentioned that they are looking to make this easier. So this might change in the future, this worked for me on 26/01/2023.

Too many templates in Django

I am learning Django and I programming a CRUD for various objects. Currently I need to generate three templates per object: one for creation, one for update and one for a list. Look at how many templates I got in the picture.
The process is becoming painful.
What I am doing wrong and how to correct it?
Thanks.
From your comment:
The problem is that If I need to make a change, for example, add a new button, I have to make it in all the templates.
That sounds wrong. Either a button belong to one type of thing and then it should only exist in that template, or it should be on every page and then it should be in the base template.
You can make one template with your basic page layout (including such buttons), and have "blocks" in them that are then filled out by each template that extends the base template.
See the Django documentation about template inheritance.
Also, I think that in most cases the "create" and "update" pages are going to be extremely similar; usually they use the same template, one with data already filled in, the other without.
You could have a base template, then a generic list template and a generic edit/create template, with templates for each type of thing extending the list and the edit templates to fill in only the relevant fields.
Also, maybe you use HTML that is close enough to what the Django forms can render themselves. Then as long as you call the edit/create form the same in each of your views (like "form"), the template can just render the form and they can all use the same template.
If you're building a big web-app then this is normal for templates to be more.
Heavy (big) web-app means = more templates + more code + more time + more features

Best Django practise - when to use views and when to use tags

I'm in the process of delving into Django into a little more depth - and I now have certain blocks around my website which are recycled, but not necessarily suited to a being placed in base.html and then sprinkled with {% extends /root/to/base.html %}.
So, I have a bespoke widget I have created which is utilised on certain pages but in different configurations, is it best to register and inclusion tag and reference the template you want to accompany those stored variables and arrays/lists/dictionaries etc..
For me it seems easier to define tags and then dot these around where I need them and just make edits to the template that is registered with that tag method? But is this the accepted Django standard?
In Django
a "view" is a callable that is responsible for handling a request and returning a response,
a template tag is a piece of code that will be executed in the context of rendering a template and will either push something in the template's context or render some text or markup.
Oranges and apples, really, and it should be quite clear when you want a view and when you want a template tag.
And yes, using inclusion tags (or a full-blown custom tag using a template to render some data) is "an accepted Django standard" - actually that's exactly what template tags are for.

How do I reverse a named Django URL to the urlpattern that defines it?

My Django app contains a couple of external references, e.g. to the application's blog, which is not part of the Django codebase and is hosted on a different subdomain.
So far, links to these were spread all around the source code as direct absolute URLs.
Now I was wondering if there was a way to use Django's excellent URL routing system for these external URLs as well. I thought I could define them like this:
url(r'^permalink/blog/$', RedirectView.as_view(url='https://blog.example.com'), name='blog'),
Then I could just reference them as {% url 'blog' %} in my templates. That works.
Now I was wondering if there was a way to resolve these directly to the 'final' URL with a special (self-defined) template tag, so that they appear as https://blog.example.com to the user, as opposed to /permalink/blog/ (to the browser) or https://app.example.com/permalink/blog/ (to the user). I do already have a self-defined {% absolute_url %} template tag, which I use in templates that require absolute URLs, like transactional email.
However, I couldn't find a way to reverse a named URL (like external:blog) to its urlpattern as opposed to its final relative URL. To do this myself, it seems like I'd have to duplicate all the code from URLNode.render(), plus urlresolvers.reverse plus probably parts of RegexURLResolver._reverse_with_prefix(). That's quite a bunch of code, but I didn't see a simpler entry point/hook into the system. Did I miss a trick there?
To summarize, I'm basically looking for a function that I can pass a named URL to, e.g.
external:blog
and get a RegexURLPattern instance back, e.g.
RegexURLPattern(r'^permalink/blog/$', RedirectView('https://blog.example.com'), {}, 'blog')
or maybe just the view might work, too.

Building a generic block-based CMS with Django

A designer recently handed me designs for a site I'm building for a client. They're great designs but I'm really scratching my head as to how I'm going to implement it on the site.
The content can very easily be broken down into blocks or chunks of data where I could allocate a textarea for text input, a couple of charfields for link-buttons, etc and sequentially render them out to the page.
The problem (eg why I'm not just pulling in Django-CMS et al) is the blocks are quite unique from each other. There are perhaps 20 different models that I would build for each block type. Rather than hack around a pre-fab CMS, I'd like to build a Page model and then just have an M2M that links to an ordered list of subclasses of my abstract Block class. I hope I'm not losing you.
I don't understand how I can do this. These questions spring to mind:
Is there a simple CMS that does all of this already? Am I wasting my time trying to figure out the physics?
My Blocks subclasses will technically be different type. Do I need generics for a M2M-through class to link to them? Is so, how do I do that?
How do I render x different forms in an inline admin context? (I'd like to have the page form with a list of the Blocks underneath)
How can the user specify the type of Block in the inline control?
Edit: Or, alternatively, what about a templatetag-based CMS?
I'm thinking of something like plonking this in my template:
{% editable 'unique_id' 'content-type' %}
A further example:
{% editable 'home-intro' 'text' %}
Then I could just stick these around the templates I want to be editable, in the way I want them to be editable and when logged in the client would see "Edit text", "Edit link", "Edit image" links which simply popped up the right field.
This would make things more locked down but the layout needs to remain solid (and the client knows nothing about HTML/CSS) so it's one or other of these methods IMO.
Couldn't you implement your 'Blocks' as Django CMS Plugins? Then each page is just constructed from a number of plugins.
Each plugin has an admin form which gets the specifics for itself, and then the page template renders the plugin as you want it.
If you look at the first page of the django-cms demo:
https://www.django-cms.org/en/tour-demo/
you'll see in (1) a highlighted plugin block - in this case a formatted text block that is edited with TinyMCE or similar. You can define your own plugins and add them to pages.
last month I published an article (for review) on how tho build a basic CMS for Jinja. This's templating language does not dffer very much from Django, which I have been using before.
You can find it here. It uses template inheritance to fill the content blocks.
https://codereview.stackexchange.com/questions/5965/review-request-jinja-cms-for-energiekantoor-nl-on-google-app-engine
Or type in Google : Jinja CMS

Categories

Resources