I'm not sure, Django CMS Blog is complete app or foundation for self-extending ? I can see one huge logical mistake - inside one app config, I can't easy change template - for list, detail, archive and item - they are strict and hardcoded in plugin code.
Is there any way to customize it without hacking the app/writing tons of custom plugins ?
I need several versions for each template - especially for blog_item.html, blog_detail.html and blog_archive.html.
I want to use plugin feature from Django CMS and don't want to hardcode whole layout in template include logic because this is broking MVC logic (!).
OK, I know, I can include my custom subtemplate blog_item in list template with instance varibles, but I totaly can't imagine, how to do it in several places - front page, list page, post page etc BUT using regular Django CMS plugin features - I have static placeholders and tpl blocks - but there still is one template for item, inside app code.
I understand (less/more) Django template inheritance, but this case is more complicated than simple inheritance between templates.
At frontpage I want different list of latest posts - one template
at category list - different layout - so next template,
inside post - detail_view - need to be customized in other way.
Can somebody guide me, how to achieve this ? Custom plugin for each layout case or something ? A bunch of IF statement in template, dependend from contex is ridiculous..
I have replaced templates set, for app config - configured templates prefix, and whole folder with articles/*.html files. But changing item subtemplate cause change layout part in many places in the same time. This is main problem. Each using "latest posts" plugin, use same template - and I can't set template files for each plugin instance.
After some tests and talks, there is no nice way to replace templates, except extending plugin class and write own better version of plugin...
Related
I need to replace same plugin template on different subpages - e.g. on frontpage I need specific slider template for latest articles, in detail article I need small list, on search result without images etc.
[note: everything about aldryn newsblog app - I don't mean my own plugin!]
*(something like custom template per plugin instance)
How to replace it ? Extending template is not quite what I need - inheritance is from bottom - from lower subtemplate to base.html - but that plugin have hardcoded lower template.
Tons of IF block in template is irrational then we think in MVC.
*( like here Render Django-CMS plugins differently on different splaceholders/templates )
Or maybe just write custom template with using hardcoded including plugins ? But using django cms placeholder editor is very useful and it'll be better to keep working in that way :///
So, I create front.html base template for frontpage,
put some plugins to placeholders - and need to replace subtemplates for this plugins only in this front.html and keep subtemplates for that plugin in other places - this is main goal.
It will be the best, when django cms / aldryn newsblog provide option "custom template" per plugin instance :|
( like this one http://www.ilian.io/django-cms-plugins-with-selectable-template/ )
If I understand your question correctly (it's late here), you need a way to override plugin templates on a plugin instance basis because hacking django templates is not the way to go (I agree).
Django CMS does allow you to override plugin templates on an instance basis.
As shown in http://docs.django-cms.org/en/develop/how_to/custom_plugins.html?highlight=get_render_template#the-simplest-plugin
In your CMSPluginBase subclass add the following:
def get_render_template(self, context, instance, placeholder):
# criteria goes here
return 'sometemplate.html'
As far as how to know which template to render when (criteria), you can do a few things.
Use the page's reverse id:
page = instance.page
templates = {
'homepage': 'plugin_home.html',
'about': 'plugin_about.html',
'contact': 'plugin_contact.html',
}
return templates[plugin.page.reverse_id]
This approach has a few drawbacks:
Relies on plugin being bound to a page. (plugins can live outside of pages)
Can only work with pages that have reverse id set and reverse ids
are unique per page which means you would have to list reverse id
for every page you want to change template for.
Use a page extension to set a category per page:
Checkout http://docs.django-cms.org/en/develop/how_to/extending_page_title.html
With this approach you can then set some sort of category to multiple pages and so you can target multiple pages in one shot like so:
page = instance.page
extension = get_page_extension(page) # Check out docs for this
templates = {
'category_1': 'plugin_category_1.html',
'category_2': 'plugin_category_2.html',
'category_3': 'plugin_category_3.html',
}
return templates[extension.category.name]
Pros:
Can target multiple pages in one shot
Cons:
Relies on plugin being bound to a page.
A bit more complex
Use a template context variable:
In your templates, depending on how you're rendering your plugins, you can
provide a context variable like so:
{% with category='category_1' %}
{% placeholder 'content' %}
{% endwith %}
or
{% with category='category_1' %}
{% render_plugin yourplugin %}
{% endwith %}
Then in your get_render_template method you can access this context variable and do the following:
# Use .get() to provide fallback
category = context['category']
templates = {
'category_1': 'plugin_category_1.html',
'category_2': 'plugin_category_2.html',
'category_3': 'plugin_category_3.html',
}
return templates[category]
Pros:
No extra models.
Can target multiple pages in one shot.
Cons:
The only one I can think of is these random {% with %} in
templates.
I completely missed the newblog part, so in order to override the newsblog plugins or any plugin, just subclass the plugin class you want to override and unregister the original and then register yours, make sure yours has the same class name.
Maybe you can make the whole template logic above into a mixin to use throughout your project.
I've always wanted to give Zinnia a look, but I'm too far into working with NewsBlog on a site right now to do it (and blogs have already been posted and whatnot). You can always just add a few extra placeholders in the template (it's not the most efficient looking thing ever, but it's no load on the framework if you add a placeholder and leave it blank), that way they aren't static, and then you can put whatever plugins you want to inside of them. You can customize each component in NewsBlog pretty easily by just adding whatever you want in the structure mode. Things get trickier when it comes to having multiple blogs that act differently, but even then, as long as you're not adding components into the static placeholders provided by NewsBlog (or as I so elegantly learned it, "don't put the stuff in the blocky-things with the pins next to them), you can create different namespace for the different blogs (either in the admin, under "Configs" in the NewsBlog section, or when creating a new page and hooking it to the NewsBlog app), and you can have different templates on different blogs.
EDIT: This is a really excellent resource for touching up NewBlog without throwing the baby out with the bathwater (after three months of learning DjangoCMS, I'm still finding myself referencing it for fine-tuning pieces of NewsBlog, and to refresh my grasp on templatetags and other things that are overwhelming and have quickly left my brain along the way): https://www.django-cms.org/en/blog/2016/02/16/build-a-website-without-knowing-python-django-part-two/
*I linked to part two, as the first part deals with how to initially setup a project, and I assumed it probably wasn't relevant. Then again, if you're using Aldryn, there are some useful bits in there that can extrapolate if you're having trouble with customizing the boilerplate (or other things you'd like to configure that an Aldryn setup handles for you -- which is super awesome most of the times, but when it's not super awesome, it's usually super frustrating :)
I have a latest news block on a page. It's a piece of markup in a template and some logic fetching the last n news in a view.
How can I make a reusable component of it (like some CMS have) which I can include in a template like this:
{% component "latest_news" "5" %}
for building a block with 5 last news.
Seems Inclusion tags is quite good for this purpose, but I wonder may be is there some build-in component-like feature in Django?
The closest to CMS's components functionality in Django is Inclusion tags
In 2021, I have come across the following projects:
https://pypi.org/project/django-render-partial/
https://pypi.org/project/django-components/
I have used django-render-partial pretty extensively, and I like that the interface allows your partials to be used in templates, or hooked directly up to a urls.py.
django-components looks pretty cool, because it allows you to package CSS and JS files with the use of a Media class (similarly to Django forms), but it fractures the "everything is a view" pattern provided by django-render-partial.
I used django_components which saved me a lot of pain, it supports creating reusable components with dynamic components name, and it also allows passing HTML fragments to the components.
Is there a shared "master" layout in Django for HTML files similar to Rails application.html.erb? If not, is there a best practice on how to go about creating one?
In Django, the best practise is to use three levels of template using template inheritance.
I quote the django book to explain you:
You can use as many levels of inheritance as needed. One common way of
using inheritance is the following three-level approach:
Create a base.html template that holds the main look and feel of
your site. This is the stuff that rarely, if ever, changes.
Create a base_SECTION.html template for each “section” of your site
(e.g., base_photos.html and base_forum.html). These templates
extend base.html and include section-specific styles/design.
Create individual templates for each type of page, such as a forum
page or a photo gallery. These templates extend the
appropriate section template.
This approach maximizes code reuse and makes it easy to add items to
shared areas, such as section-wide navigation.
New to Django. In the Django docs, I know it says "Custom template tags and filters must live inside a Django app.". I am going to have 4 or 5 apps, each with custom template tags (some of which will be the same tags as those in other apps). Even though it says that, is it possible to make one master folder for all of my template tags at the root of my project? It seems like having separate folders for each app violates D.R.Y....
Well, there's no reason to have duplicate tags; a template tag library in any app can be loaded from any template. You should only have one copy of any tag.
That said, what's commonly done is to create a template tag APP to house all template tags.
Just build a blank application called tags, utils, whatever, and put all template tags in that app.
root/utils/templatetags
It doesn't even need a model.py/urls.py to function in installed_apps.
You could make an app thats only purpose is to handle some general things like template tags or utils. Sometimes I do this and just call it "app".
But even if you keep things the way they are, there is no reason to duplicate template tags because they are available in all templates anyway. Unless you plan on breaking the apps up and using them in different projects, just put the template tag in the appropriate app, and load it from a template.
I am very new to Typo3, and I have a very basic (not to say dumb) question: is it possible to have multiple page templates or can you only have one template?
What I need to do is have different templates call different scripts because apparently having the same template call all of them seems to create conflicts.
Thank you for your help!
Jane
Using TypoScript, you can include any number of scripts in your template.
You can even imagine the following page tree:
-Home
--Page 1
--Page 2
---Page A
---Page B
--Page 3
You can set a certain template for the homepage, and it will apply to all pages. But you can set a completely different template for page 3, and it will only apply to that page. You can also apply a slightly different template to page 2, overriding specific values (page background, CSS inclusion, etc), and it will apply to Page A and Page B as well.
yes, you can have many different templates on a site. Actually each single page can have its very own template. You might be interested in checking out templavoila since its very graphical and once you got it set up, you can easily change between templates within the Typo3 backend.
Tutorials
An alternative would be to use the original TypoScript templates which is not difficult yet requires a bit of TypoScript understanding.
TypoScript Templates
In any way you can chose between different templates.