How to add a contact form template into another template? - django

I'm very new to this and I'm trying to create a simple website for a company using django 2.
I'm using this template that is a single page: https://html5up.net/astral
I want to make the contact form work but I can't manage.
I've tried putting {% block %} {% endblock %} in the HTML file but it won't render the form, {% include %} renders the html file I created but not the form. I was wondering if it is possible to make the form that is already rendered work.
Thanks!

You can use Template Inheritance to do this.
You have your "base.html" parent template which has a placeholder for the form:
<html>
...
<div ... >
{% block contact-form %}
{% endblock %}
</div>
...
</html>
And your form is in "contact.html" child template:
{% extends "base.html" %}
{% block contact-form %}
<!-- contact form content -->
{% endblock %}
Then in your url patterns direct peeps to the view that renders the child "contact.html" template.
The {% extends %} tag lets the template engine know that it must first load the parent "base.html" and then fill in the appropriate block with the child "contact.html" template's content.

Related

About parametrizing base template page in Django

I have the following problem, there is a base template "base.html" which defines default header and body information, which will be used by other pages.
The base page contains the rendered parameter, which depends on the request time in a non trivial way.
base.html
<!DOCTYPE html>
<head>
...
{% block head_stuff %} {% endblock %}
...
</head>
<body>
...
<p>Parameter that depends on the request time</p>
...
{% block body_stuff %} {% endblock %}
...
</body>
</html>
The pages that use it look like:
a.html b.html c.html
{% extends "base.html" %}
{% block head_stuff %} ... {% endblock %}
{% block body_stuff %} ... {% endblock %}
What I'd like to do is to render a.html, b.html, c.html without passing informations about that parameter to these pages in their views or templates.
In absence of inheritance, one would call render function by passing the parameter to a context, but in this case no views are used to construct the base.html.
How can I approach this problem?
A context processor is a function that takes request as an argument and returns a dictionary. The contents of this dictionary are then appended to the context of every template. So if you had a context process or
def my_example(request):
return dict(
name="steve",
dynamic_thing=some_other_function()
)
Then the templates could access these using {{ name }} and {{ dynamic_thing }}

Twig block passed to embedded template

I'm using twig templates in a slim framework app. I have a template page.phtml which paginates an array of data and has several sub blocks intended for overriding per element specifics like paginating users, events, orders, etc.
page.phtml
<div class="page">
{% block block1 %}default content{% endblock %}
<ul>
...
</ul>
{% block block2 %}{% endblock %}
</div>
I have an event.phtml template which embeds page.phtml and adds some other content to the page; it also overrides the default page's block1 content
event.phtml
<html>
<body>
<h1>Event Page</h1>
{% embed "page.phtml" %}
{% block block1 %}event page content{% endblock %}
{% endembed %}
</body>
</html>
I have a custom event page which needs only modify a few of the event page's blocks so I extended event.phtml like so
custom_event.phtml
{% extends "event.phtml" %}
{% block block2 %}overridden value{% endblock %}
and expected block2's overridden content to show up in the page.phtml template embedded by the parent template. I can output the value of block2 in the parent template and it's there, but in the embedded template it's not. I tried explicitly passing the block in event.phtml in the embed like so
{%embed "page.phtml" %}
{% block block2 %}{{parent()}}{% endblock %}
...
{% endembed %}
But that yielded no difference. How do I get the overridden block2 from the custom_event.phtml template all the way through the extended event.phtml template and into the embedded page.phtml template?
You cannot do this.
{% embed %} technically defines a new (anonymous) template which extends the embedded template (this is how it can overwrite blocks) and gets included into the current templating. This is really just syntactic sugar for {% include %} and {% extends %} to avoid having to store this partial template in its own file and include it only once.
Twig inclusion are not extendable by child templates. Only blocks of the current template are available for extension. And event.phtml does not have any blocks.

Django-CMS show_placeholder not working as expected

I'm working on a site where the footer content is shared across all pages. What is the best way to do in Django-CMS?
I tried using show_placeholder tag, but it somehow didn't work. A little more details on what I did:
First, I have a {% placeholder footer_info %} in base.html. Then I add a page called "Home" (template homepage.html) in django admin and put some text under footer_info as a Text plugin. As the accepted answer in this question suggested (http://stackoverflow.com/questions/3616745/how-to-render-django-cms-plugin-in-every-page),
I add
{% placeholder footer_info or %}
{% show_placeholder footer_info "Home" %}
{% endplaceholder %}
In a template called services.html which I used as the template for page Services.
However, the content in home page is not showing up in services page. I also tried adding an id home_cms_page to home page in the Advanced option area, so that I can reference it in services.html like this:
{% placeholder footer_info or %}
{% show_placeholder footer_info "home_cms_page" %}
{% endplaceholder %}
But the content is still not showing up.
Could anyone tell me what I am doing wrong? And is this the best way of getting some content from a page across all other pages (and I have to add show_placeholder in every other page)?
Thank you
EDIT:
It is not a multilingual site. I commented out 'cms.middleware.multilingual.MultilingualURLMiddleware', because the only language I use on the site is English.
I have this in my base.html:
{% load cms_tags sekizai_tags %}
<!-- all the rest of the HTML markups -->
<div class="span4">
{% placeholder footer_info %}
</div>
Then I added a page in the admin called "Home" with a Text plugin and an id of "home_cms_page".
The following is in my services.html:
{% extends "base.html" %}
{% load cms_tags %}
{% block base_content %}
{% placeholder services_info %}
{% endblock base_content %}
{% block page_content %}
Home page
{% endblock page_content %}
{% placeholder "footer_info" or %}
{% show_placeholder "footer_info" "home_cms_page" %}
{% endplaceholder %}
Read the documentation:
If you know the exact page you are referring to, it is a good idea to
use a reverse_id (a string used to uniquely name a page) rather than a
hard-coded numeric ID in your template. For example, you might have a
help page that you want to link to or display parts of on all pages.
To do this, you would first open the help page in the admin interface
and enter an ID (such as help) under the ‘Advanced’ tab of the form.
Then you could use that reverse_id with the appropriate templatetags:
{% show_placeholder "right-column" "help" %}
I added "index" in the advanced options of the index page, and added {% show_placeholder "banner" "index" %} in the base template. It all works.

Embedded controller views with assets

I am currently working on a symfony2 application and am using embedded controllers. My embedded controllers are like widgets which should encapsulate its own set of functionality and can be embedded anywhere and still be expected to function.
I have a controller called users online. The view it generates is simple, just a list of online users. But, I would like to add some javascript to that view so that I can use ajax to retrieve information for a user that's clicked on.
The controller basically returns a view:
return $this->render('AppBundle:Users:usersOnline.html.twig', array('somedata' => $data);
Here's the view for that controller:
{% extends partial.html.twig" %}
{% block content %}
<ul>
<li>User 1</li> (this would all be generated using 'somedata')
<li>User 2</li>
....
<ul>
{% endblock content %}
{% block scripts %}
..some javascript for interacting with this widget
{% endblock %}
This is the partial that is extended from:
{% block content %}
{% endblock content %}
{% block scripts %}{% endblock %}
Here's the main page that embeds the controller:
{% "base.html.twig" %}
{% block title %}Main{% endblock %}
{% block content %}
..some markup here
<div id="usersonline">
{% render "AppBundle:Users:usersOnline" with {'max': 4} %}
</div>
{% endblock %}
{% block scripts %}
..some javascript
{% endblock %}
This is the base that it extends:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{% block title %}{% endblock %} - App</title>
...Some stylesheets
</head>
<body>
{% block content %}{% endblock %}
<script src="http://yui.yahooapis.com/3.5.0pr2/build/yui/yui-min.js"></script>
{% block scripts %}{% endblock %}
</body>
</html>
The problem I am facing now is including javascripts from the embedded controller. In my case, the view extends partial and is fully rendered as 1 unit before it is inserted into the main page. In this case, I can only put my javascript in the content block, which means I will have <script> tags within <div> tags. I would also prefer to have scripts at the end of the body for user interface performance.
How should I structure my templates (or is it even possible) so that I can render the appropriate pieces from an embedded controller's view into appropriate blocks in the template that embeds the controller? In my current template the YUI library would be loaded after the embedded controller's rendered HTML markup, so accessing using the YUI library within the embedded controller would be impossible.
I have written an extension which is essentially a token parser to deal with this. The documentation for the token parser is very sparse and the code is also mostly uncommented, so it took a bit of fiddling around to get working.
I have structured the parser so that at the beginning, you would declare something (similiar to {% use %}):
{% myparser "AppBundle:Users:usersOnline" with {'max': 4} as xyz %}
Then blocks like xyzcontent would be avaliable and then you just render them in the appropriate places using {{ block('xyzcontent') }}. It works quite well. However the following does not work:
{% set max = 4 %}
{% myparser "AppBundle:Users:usersOnline" with {'max': max} as xyz %}
I could not find a way to evaluate an expression and get its value directly within the token parser. For the most part it works fine, except for this problem.
If someone has some idea as to how to get the value of a variable within the token parser, it would be great :)
After one day of looking for a satisfying solution, I finally choose for the following approach:
Render a controller for your widget's functionality (like you are already doing);
Render templates to embed your widget's assets (controllers are not needed and will waste your performance). Ignore include if the template doesn't exist.
Use a consistent naming convention to make the widget functionality more dynamic.
Example for one widget:
{% "base.html.twig" %}
{% block title %}Main{% endblock %}
{% block content %}
..some markup here
<div id="usersonline">
{{ render(controller("AppBundle:Users:usersOnline", {'max': 4})) }}
</div>
{% endblock %}
{% block scripts %}
{{ include("AppBundle:Users:usersOnline_js.html.twig" ignore missing }}
{% endblock %}
{% block stylesheets %}
{{ include("AppBundle:Users:usersOnline_css.html.twig" ignore missing }}
{% endblock %}
(As you can see, I use the Symfony 2.2 way of including and embedding)
Or, a more dynamic way of widget rendering:
{% "base.html.twig" %}
{% block title %}Main{% endblock %}
{% block widgets %}
..some markup here
{% for widget in widgets %}
{{ render(controller(widget.controller ~ ':widget', widget.options)) }}
{% endfor %}
{% endblock %}
{% block scripts %}
{% for widget in widgets %}
{{ include(widget.controller ~ ':widget_js.html.twig' ignore missing }}
{% endfor %}
{% endblock %}
{% block stylesheets %}
{% for widget in widgets %}
{{ include(widget.controller ~ ':widget_css.html.twig' ignore missing }}
{% endfor %}
{% endblock %}
My conclusion
Rendering multiple controllers in one page, while "merging" it's templates blocks, cannot be achieved out of the box in Symfony2. Symfony2 has always been focusing on one controller for each request, which explains why multiple controllers outputs are separated and hard to combine.
I think the Symfony CMF has (or will have) a proper solution for this, because this whole widget topic is more applied in dynamic content managed websites.
Anyway, I think my way of combining embedded controllers and included templates is the best approach for Symfony 2 so far.
The alternatives, in my opinion, do have to many disadvantages:
Using multiple controllers: too heavy and not needed because assets won't need any controller.
Loading the widgets assets directly in the page: hard to maintain when changing widgets / assets.

Django admin: adding pagination links in list of objects to top

Is it possible to have the pagination links that appear at the bottom of a list of objects in Django's admin interface at the top as well?
Can this be done without changing the admin templates? I suspect not, given the lack of a ModelAdmin option, but thought I'd see if anyone had done this before I dug into the template code.
I really, really don't want to have to copy and paste change_list.html into a new file, just so I can add a pagination line - that'll make changing Django versions painful, since I'll have to check if anything's changed in that file, and re-apply my change.
Do not copy change_list.html, instead create a new template that extends it:
{% extends "admin/change_list.html" %}
{% block result_list %}
{% block pagination %} {{ block.super }} {% endblock %} <!-- pagination -->
{{ block.super }} <!-- rest of results list -->
{% endblock %}
Then pass the new template's name to ModelAdmin in change_list_template attribute - doc here.
The source code implementing the django admin template for change_list.html has a content block so if you create a file change_list.html under 'admin' folder in your templates directory and add this:
{% extends "admin/change_list.html" %}
{# added pagination to top as well as bottom #}
{% block content %}{% pagination cl %}{{ block.super }}{% endblock %}
it should do the trick!