return self.name
-class Block(RichText, Titled, Orderable):
+class Block(Titled, RichText, Orderable):
with_separator = models.BooleanField(default=False)
background_color = models.CharField(_('background color'), max_length=32, choices=COLOR_CHOICES, blank=True)
filter_horizontal = ['authors']
+class ProjectBlogPageInline(StackedDynamicInlineAdmin):
+
+ model = ProjectBlogPage
+
+
class ProjectAdmin(admin.ModelAdmin):
model = Project
ProjectLinkInline,
ProjectFileInline,
ProjectRelatedTitleAdmin,
- DynamicContentProjectInline]
+ DynamicContentProjectInline,
+ ProjectBlogPageInline,]
filter_horizontal = ['teams', 'organizations']
list_filter = ['type', 'program', 'program_type', null_filter('external_id')]
list_display = ['title', 'external_id', 'date_from', 'date_to', 'status', 'admin_link']
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.11 on 2017-01-04 16:33
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+import mezzanine.core.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('sites', '0002_alter_domain_unique'),
+ ('organization-projects', '0036_auto_20170103_1227'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='ProjectBlogPage',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('keywords_string', models.CharField(blank=True, editable=False, max_length=500)),
+ ('title', models.CharField(max_length=500, verbose_name='Title')),
+ ('title_fr', models.CharField(max_length=500, null=True, verbose_name='Title')),
+ ('title_en', models.CharField(max_length=500, null=True, verbose_name='Title')),
+ ('slug', models.CharField(blank=True, help_text='Leave blank to have the URL auto-generated from the title.', max_length=2000, null=True, verbose_name='URL')),
+ ('_meta_title', models.CharField(blank=True, help_text='Optional title to be used in the HTML title tag. If left blank, the main title field will be used.', max_length=500, null=True, verbose_name='Title')),
+ ('description', models.TextField(blank=True, verbose_name='Description')),
+ ('description_fr', models.TextField(blank=True, null=True, verbose_name='Description')),
+ ('description_en', models.TextField(blank=True, null=True, verbose_name='Description')),
+ ('gen_description', models.BooleanField(default=True, help_text='If checked, the description will be automatically generated from content. Uncheck if you want to manually set a custom description.', verbose_name='Generate description')),
+ ('created', models.DateTimeField(editable=False, null=True)),
+ ('updated', models.DateTimeField(editable=False, null=True)),
+ ('status', models.IntegerField(choices=[(1, 'Draft'), (2, 'Published')], default=2, help_text='With Draft chosen, will only be shown for admin users on the site.', verbose_name='Status')),
+ ('publish_date', models.DateTimeField(blank=True, db_index=True, help_text="With Published chosen, won't be shown until this time", null=True, verbose_name='Published from')),
+ ('expiry_date', models.DateTimeField(blank=True, help_text="With Published chosen, won't be shown after this time", null=True, verbose_name='Expires on')),
+ ('short_url', models.URLField(blank=True, null=True)),
+ ('in_sitemap', models.BooleanField(default=True, verbose_name='Show in sitemap')),
+ ('content', mezzanine.core.fields.RichTextField(verbose_name='Content')),
+ ('content_fr', mezzanine.core.fields.RichTextField(null=True, verbose_name='Content')),
+ ('content_en', mezzanine.core.fields.RichTextField(null=True, verbose_name='Content')),
+ ('project', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='blog_pages', to='organization-projects.Project', verbose_name='project')),
+ ('site', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site')),
+ ],
+ options={
+ 'verbose_name_plural': 'Project blog pages',
+ 'verbose_name': 'Project blog page',
+ },
+ ),
+ ]
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.11 on 2017-01-04 17:00
+from __future__ import unicode_literals
+
+from django.db import migrations
+import mezzanine.core.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('organization-projects', '0037_projectblogpage'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='projectblogpage',
+ name='login_required_content',
+ field=mezzanine.core.fields.RichTextField(null=True, verbose_name='Login required content'),
+ ),
+ ]
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.11 on 2017-01-04 17:20
+from __future__ import unicode_literals
+
+from django.db import migrations
+import mezzanine.core.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('organization-projects', '0038_projectblogpage_login_required_content'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='projectblogpage',
+ name='login_required_content_en',
+ field=mezzanine.core.fields.RichTextField(null=True, verbose_name='Login required content'),
+ ),
+ migrations.AddField(
+ model_name='projectblogpage',
+ name='login_required_content_fr',
+ field=mezzanine.core.fields.RichTextField(null=True, verbose_name='Login required content'),
+ ),
+ ]
class Meta:
verbose_name = 'Dynamic Content Project'
+
+
+class ProjectBlogPage(Displayable, RichText):
+
+ project = models.ForeignKey(Project, verbose_name=_('project'), related_name='blog_pages', blank=True, null=True, on_delete=models.SET_NULL)
+ login_required_content = RichTextField(_("Login required content"), null=True)
+
+ class Meta:
+ verbose_name = 'Project blog page'
+ verbose_name_plural = 'Project blog pages'
+
+ def get_absolute_url(self):
+ return reverse("organization-project-blogpage-detail", kwargs={"slug": self.slug})
fields = ('title', 'description', 'content')
+@register(ProjectBlogPage)
+class ProjectBlogPageTranslationOptions(TranslationOptions):
+
+ fields = ('title', 'description', 'content', 'login_required_content')
+
+
@register(ProjectLink)
class ProjectLinkTranslationOptions(TranslationOptions):
url("^project/detail/(?P<slug>.*)/$", ProjectDetailView.as_view(), name='organization-project-detail'),
url("^dynamic-content-project/$", permission_required('project.can_edit')(DynamicContentProjectView.as_view()), name='dynamic-content-project'),
url("^project/demo/(?P<slug>.*)/$", ProjectDemoDetailView.as_view(), name='organization-project-demo-detail'),
+ url("^project/blog/(?P<slug>.*)/$", ProjectBlogPageView.as_view(), name='organization-project-blogpage-detail'),
]
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.shortcuts import render
+from django.views.generic.detail import SingleObjectMixin
from dal import autocomplete
from dal_select2_queryset_sequence.views import Select2QuerySetSequenceView
from mezzanine_agenda.models import Event
from organization.pages.models import CustomPage
-class ProjectMixin(object):
+class ProjectMixin(SingleObjectMixin):
+
+ def get_context_data(self, **kwargs):
+ context = super(ProjectMixin, self).get_context_data(**kwargs)
+ self.object = self.get_object()
+ if not isinstance(self.object, Project):
+ self.project = self.object.project
+ else:
+ self.project = self.object
- def get_context_data_mixin(self, context):
department = None
if self.project.lead_team:
model = Project
template_name='projects/project_detail.html'
- context_object_name = 'project'
-
- def get_context_data(self, **kwargs):
- context = super(ProjectDetailView, self).get_context_data(**kwargs)
- self.project = self.get_object()
- self.get_context_data_mixin(context)
- context['next'] = reverse_lazy('organization-project-detail', kwargs={'slug': self.project.slug})
- return context
class DynamicContentProjectView(Select2QuerySetSequenceView):
model = ProjectDemo
template_name='projects/project_demo_detail.html'
- context_object_name = 'demo'
- def get_context_data(self, **kwargs):
- context = super(ProjectDemoDetailView, self).get_context_data(**kwargs)
- demo = self.get_object()
- project = demo.project
- self.get_context_data_mixin(context)
- return context
+
+class ProjectBlogPageView(SlugMixin, ProjectMixin, DetailView):
+
+ model = ProjectBlogPage
+ template_name='projects/project_blogpage_detail.html'
{% block page_demo %}
{% endblock %}
+ {% block page_blog %}
+ {% endblock %}
+
{% block page_sub_content %}
{% with object.blocks.all as blocks %}
{% include "core/inc/block.html" %}
{% if block.login_required and not user.is_authenticated %}
<div class="chapo">
{% trans "Please login to get links to the data" %}<br><br>
- <a class="button" href="{% url 'login' %}?next={{ next }}#section-0" title="Login">{% trans "Login" %}</a>
+ <a class="button" href="{% url 'login' %}?next={{ request.path }}" title="Login">{% trans "Login" %}</a>
</div>
{% else %}
{% if block.content %}
--- /dev/null
+{% extends "pages/page.html" %}
+{% load i18n mezzanine_tags keyword_tags pages_tags organization_tags %}
+
+{% block meta_title %}{% trans "Demo" %}{% endblock %}
+
+{% block meta_description %}
+ {% metablock %}
+ {{ object.description }}
+ {% endmetablock %}
+{% endblock %}
+
+{% block page_class %}
+ projectblogpage
+{% endblock %}
+
+{% block breadcrumb_menu %}
+ {{ block.super }}
+ <li class="breadcrumb__item"><a class="breadcrumb__link" href="{% url 'organization-project-detail' object.project.slug %}">{{ object.project.title }}</a></li>
+ <li class="breadcrumb__item active">{{ object.title }}</li>
+{% endblock %}
+
+{% block page_title %}
+ {% editable project.title %}
+ <h1 class="dotted">{{ object.title }}</h1>
+ {% endeditable %}
+
+ {% if object.description %}
+ {% editable object.description %}
+ <div class="chapo">
+ {{ object.description }}
+ </div>
+ {% endeditable %}
+ {% endif %}
+{% endblock %}
+
+{% block page_sidebar %}
+{% endblock %}
+
+{% block page_slider %}
+{% endblock %}
+
+{% block page_content %}
+ {% if project.content %}
+ {% editable project.content %}
+ {{ object.content|richtext_filters|safe }}
+ {% endeditable %}
+ {% endif %}
+ {% if object.login_required_content and not user.is_authenticated %}
+ <div class="chapo" id="login_required_content">
+ {% trans "Please login to get more data." %}<br><br>
+ <a class="button" href="{% url 'login' %}?next={{ request.path }}#login_required_content" title="Login">{% trans "Login" %}</a>
+ </div>
+ {% else %}
+ {% editable block.content %}
+ {{ object.login_required_content|richtext_filters|safe }}
+ {% endeditable %}
+ {% endif %}
+{% endblock %}
{% extends "pages/page.html" %}
{% load mezzanine_tags keyword_tags i18n organization_tags pages_tags %}
-{% block meta_title %}{{ project.meta_title }}{% endblock %}
+{% block meta_title %}{{ object.meta_title }}{% endblock %}
{% block meta_keywords %}{% metablock %}
-{% keywords_for project as keywords %}
+{% keywords_for object as keywords %}
{% for keyword in keywords %}
{% if not forloop.first %}, {% endif %}
{{ keyword }}
{% endmetablock %}{% endblock %}
{% block page_class %}
- project
+ object
{% endblock %}
{% block body_class %}
{% block breadcrumb_menu %}
{{ block.super }}
- <li class="breadcrumb__item active">{{ project.title }}</li>
+ <li class="breadcrumb__item active">{{ object.title }}</li>
{% endblock %}
{% block page_tags %}
{% block page_title %}
- {% editable project.title %}
- <h1 class="dotted">{{ project.title }}</h1>
+ {% editable object.title %}
+ <h1 class="dotted">{{ object.title }}</h1>
{% endeditable %}
{% with page.get_ascendants|last as top_level_parent %}
{% endif %}
{% endwith %}
- {% if project.description %}
- {% editable project.description %}
+ {% if object.description %}
+ {% editable object.description %}
<div class="chapo">
- {{ project.description }}
+ {{ object.description }}
</div>
{% endeditable %}
{% endif %}
{% endblock %}
{% block page_content %}
- {% if project.content %}
- {% editable project.content %}
- {{ project.content|richtext_filters|safe }}
+ {% if object.content %}
+ {% editable object.content %}
+ {{ object.content|richtext_filters|safe }}
{% endeditable %}
{% endif %}
{% endblock %}
<a class="nav-tree__link" href="{{ page.get_absolute_url }}">{{ page.title }}</a>
</li>
<li class="nav-tree__item">
- <a class="nav-tree__link active" href="{{ page.get_absolute_url }}">{{ project.title }}</a>
+ <a class="nav-tree__link active" href="{{ page.get_absolute_url }}">{{ object.title }}</a>
<ul class="nav-tree" data-summary>
<li class="nav-tree__item nav-tree__item--sub hide">
<a class="nav-tree__link nav-tree__link--sub" href="#"></a>
{% endblock %}
{% block page_link %}
- {% with project.links.all as links %}
+ {% with object.links.all as links %}
{% if links %}
{% include 'core/inc/link.html' %}
{% endif %}
{% endblock %}
{% block page_audio %}
- {% with project as object %}
+ {% with object as object %}
{{ block.super }}
{% endwith %}
{% endblock %}
{% block page_slider %}
- {% with project as object %}
+ {% with object as object %}
{{ block.super }}
{% endwith %}
{% endblock %}
{% block page_video %}
- {% with project as object %}
+ {% with object as object %}
{{ block.super }}
{% endwith %}
{% endblock %}
{% block page_sub_content %}
- {% if project.type == 'external' %}
+ {% if object.type == 'external' %}
<div class="white-bg pb2">
<hr class="mt0 invisible" />
<div class="page__block page__block--yellow">
<h3 class="dotted project-details__title">{% trans "Project details" %}</h3>
<div>
- {% if project.program %}
+ {% if object.program %}
<div class="project-details__item">
<div class="project-details__item-title">
{% trans "Program" %}
</div>
<div class="project-details__item-desc">
- {{ project.program }}
+ {{ object.program }}
</div>
</div>
{% endif %}
- {% if project.program_type %}
+ {% if object.program_type %}
<div class="project-details__item">
<div class="project-details__item-title">
{% trans "Program type" %}
</div>
<div class="project-details__item-desc">
- {{ project.program_type }}
+ {{ object.program_type }}
</div>
</div>
{% endif %}
{% trans "Beginning" %}
</div>
<div class="project-details__item-desc">
- {{ project.date_from }}
+ {{ object.date_from }}
</div>
</div>
{% trans "End" %}
</div>
<div class="project-details__item-desc">
- {{ project.date_to }}
+ {{ object.date_to }}
</div>
</div>
{% trans "Status" %}
</div>
<div class="project-details__item-desc">
- {{ project.project_status }}
+ {{ object.object_status }}
</div>
</div>
- {% if project.website %}
+ {% if object.website %}
<div class="project-details__item">
<div class="project-details__item-title">
{% trans "Website" %}
</div>
<div class="project-details__item-desc">
- <a href="{{ project.website }}" target="_blank" title="{{ project.title }}">{{ project.website }}</a>
+ <a href="{{ object.website }}" target="_blank" title="{{ object.title }}">{{ object.website }}</a>
</div>
</div>
{% endif %}
<div class="project-details__logo">
- {% with project.images.all|get_type:'logo' as images %}
+ {% with object.images.all|get_type:'logo' as images %}
{% include 'core/inc/logo.html' %}
{% endwith %}
</div>
<div>
- {% if project.lead_team or project.lead_organization %}
+ {% if object.lead_team or object.lead_organization %}
<div class="project-details__item">
- {% if project.lead_team %}
+ {% if object.lead_team %}
<div class="project-details__item-title">
{% trans "Project lead team" %}
</div>
<div class="project-details__item-desc">
- <a href="{% url "page" project.lead_team.pages.all.0 %}">{{ project.lead_team.short }}</a>
+ <a href="{% url "page" object.lead_team.pages.all.0 %}">{{ object.lead_team.short }}</a>
</div>
- {% elif project.lead_organization %}
+ {% elif object.lead_organization %}
<div class="project-details__item-title">
{% trans "Project lead organization" %}
</div>
<div class="project-details__item-desc">
- {% if project.lead_organization.url %}
- <a href="{{ project.lead_organization.url }}" target="_blank" title="{{ project.lead_organization }}">
+ {% if object.lead_organization.url %}
+ <a href="{{ object.lead_organization.url }}" target="_blank" title="{{ object.lead_organization }}">
{% endif %}
- {{ project.lead_organization }}
- {% if project.lead_organization.url %}
+ {{ object.lead_organization }}
+ {% if object.lead_organization.url %}
</a>
{% endif %}
</div>
{% trans "Partners" %}
</div>
<div class="project-details__item-desc">
- {% for organization in project.organizations.all %}
+ {% for organization in object.organizations.all %}
{% if organization.url %}
<a href="{{ organization.url }}" target="_blank" title="{{ organization }}">
{% endif %}
{% trans "teams" %} ({{ host_organization }})
</div>
<div class="project-details__item-desc">
- {% for team in project.teams.all %}
+ {% for team in object.teams.all %}
{% if team.pages.all %}
<a href="{% url "page" team.pages.all.0.slug %}">{{ team.short }}</a><br>
{% endif %}
</div>
{% endif %}
- {% with project.blocks.all as blocks %}
+ {% with object.blocks.all as blocks %}
{% include "projects/inc/project_block.html" %}
{% endwith %}
{% endblock %}
{% block page_demo %}
-{% if project.demos.all %}
+{% if object.demos.all %}
<div class="page__block{% if block.background_color %} page__block--{{ block.background_color }}{% endif %}">
<hr class="mt0">
<div class="white-bg mb2">
<div class="col-sm-9 col-sm-push-3 col-lg-8 col-lg-push-2">
<ul>
<h2>{% trans "Demos" %}</h2>
- {% for demo in project.demos.all %}
+ {% for demo in object.demos.all %}
<li><a href="{% url 'organization-project-demo-detail' demo.slug %}">{{ demo.title }}</a></li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}
+{% block page_blog %}
+{% if object.blog_pages.all %}
+<div class="page__block{% if block.background_color %} page__block--{{ block.background_color }}{% endif %}">
+ <hr class="mt0">
+ <div class="white-bg mb2">
+ <div class="container">
+ <div class="row" data-summary-content>
+ <div class="col-sm-9 col-sm-push-3 col-lg-8 col-lg-push-2">
+ <ul>
+ <h2>{% trans "Blog Pages" %}</h2>
+ {% for blog_page in object.blog_pages.all %}
+ <li><a href="{% url 'organization-project-blogpage-detail' blog_page.slug %}">{{ blog_page.title }}</a></li>
+ {% endfor %}
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+{% endif %}
+{% endblock %}
+
{% block logo %}
- {% if project.organizations.all|length > 0 %}
+ {% if object.organizations.all|length > 0 %}
<div class="page__block{% if block.background_color %} page__block--{{ block.background_color }}{% endif %}">
<div class="white-bg pb2">
<div class="container">
<div class="row" data-summary-content>
<div class="col-sm-9 col-sm-push-3 col-lg-8 col-lg-push-2">
<ul class="partners-list">
- {% if project.lead_organization %}
- {% with project.lead_organization.images.all|get_type:'logo' as images %}
+ {% if object.lead_organization %}
+ {% with object.lead_organization.images.all|get_type:'logo' as images %}
{% include 'core/inc/logo.html' %}
{% endwith %}
{% endif %}
- {% for organization in project.organizations.all %}
+ {% for organization in object.organizations.all %}
{% with organization.images.all|get_type:'logo' as images %}
{% include 'core/inc/logo.html' %}
{% endwith %}
{% endblock %}
{% block page_related_content %}
- {% with dynamic_content=project.dynamic_content_project.all object=project %}
+ {% with dynamic_content=object.dynamic_content_object.all object=object %}
{% include "core/inc/related_content.html" %}
{% endwith %}
{% endblock %}