|
@@ -19,29 +19,23 @@ Prep work for custom pages
|
|
|
--------------------------
|
|
|
|
|
|
We need to plan our page ahead of time. What fields will our custom page need, and what will we need our page
|
|
|
-to do? Take the time to write down the answer to these questions before you even touch the code. This is what
|
|
|
-we are writing down for Simple Sweet Dessert's custom cupcake page:
|
|
|
+to do? In this example we are going to add a products page and a product landing page. As we add more products
|
|
|
+they will automatically be included on the landing page like articles. For this example, we have to decide what fields we need.
|
|
|
|
|
|
-**Our Prep Notes**
|
|
|
|
|
|
-1. We want our page to page to list the attributes and descriptions of individual cupcakes.
|
|
|
+**Product Page Fields:**
|
|
|
|
|
|
-2. We want to be able to display the cupcakes in cards automatically on a landing page.
|
|
|
+* Name of the product (This will be the title of the page in this instance)
|
|
|
|
|
|
+* Photo of the product
|
|
|
|
|
|
-**Cupcake Page Fields:**
|
|
|
+* Description of the product
|
|
|
|
|
|
-* Name of cupcake (This could be the title of the page)
|
|
|
+* Does this product require a prescription.
|
|
|
|
|
|
-* Photo of cupcake
|
|
|
+**Product Landing Page Fields:**
|
|
|
|
|
|
-* Description of cupcake
|
|
|
-
|
|
|
-* Days when these cupcakes are made
|
|
|
-
|
|
|
-**Cupcake Landing Page Fields:**
|
|
|
-
|
|
|
-* Needs to be the parent page for the cupcake pages
|
|
|
+* Needs to be the parent page for the product pages
|
|
|
|
|
|
Setting up the page models
|
|
|
--------------------------
|
|
@@ -63,7 +57,7 @@ frameworks that we are using.
|
|
|
CoderedArticleIndexPage,
|
|
|
CoderedEmail,
|
|
|
CoderedFormPage,
|
|
|
- CoderedWebPage
|
|
|
+ CoderedWebPage,
|
|
|
)
|
|
|
|
|
|
|
|
@@ -71,69 +65,30 @@ frameworks that we are using.
|
|
|
"""
|
|
|
Article, suitable for news or blog content.
|
|
|
"""
|
|
|
- class Meta:
|
|
|
- verbose_name = 'Article'
|
|
|
- ordering = ['-first_published_at']
|
|
|
-
|
|
|
- # Only allow this page to be created beneath an ArticleIndexPage.
|
|
|
- parent_page_types = ['website.ArticleIndexPage']
|
|
|
-
|
|
|
- template = 'coderedcms/pages/article_page.html'
|
|
|
- search_template = 'coderedcms/pages/article_page.search.html'
|
|
|
-
|
|
|
-
|
|
|
- class ArticleIndexPage(CoderedArticleIndexPage):
|
|
|
- """
|
|
|
- Shows a list of article sub-pages.
|
|
|
- """
|
|
|
- class Meta:
|
|
|
- verbose_name = 'Article Landing Page'
|
|
|
-
|
|
|
- # Override to specify custom index ordering choice/default.
|
|
|
- index_query_pagemodel = 'website.ArticlePage'
|
|
|
-
|
|
|
- # Only allow ArticlePages beneath this page.
|
|
|
- subpage_types = ['website.ArticlePage']
|
|
|
-
|
|
|
- template = 'coderedcms/pages/article_index_page.html'
|
|
|
-
|
|
|
-
|
|
|
- class FormPage(CoderedFormPage):
|
|
|
- """
|
|
|
- A page with an html <form>.
|
|
|
- """
|
|
|
- class Meta:
|
|
|
- verbose_name = 'Form'
|
|
|
-
|
|
|
- template = 'coderedcms/pages/form_page.html'
|
|
|
|
|
|
-
|
|
|
- class FormPageField(CoderedFormField):
|
|
|
- """
|
|
|
- A field that links to a FormPage.
|
|
|
- """
|
|
|
class Meta:
|
|
|
- ordering = ['sort_order']
|
|
|
+ verbose_name = "Article"
|
|
|
+ ordering = ["-first_published_at"]
|
|
|
|
|
|
- page = ParentalKey('FormPage', related_name='form_fields')
|
|
|
+ # Only allow this page to be created beneath an ArticleIndexPage.
|
|
|
+ parent_page_types = ["website.ArticleIndexPage"]
|
|
|
|
|
|
+ template = "coderedcms/pages/article_page.html"
|
|
|
+ search_template = "coderedcms/pages/article_page.search.html"
|
|
|
|
|
|
- class FormConfirmEmail(CoderedEmail):
|
|
|
- """
|
|
|
- Sends a confirmation email after submitting a FormPage.
|
|
|
- """
|
|
|
- page = ParentalKey('FormPage', related_name='confirmation_emails')
|
|
|
|
|
|
+ ## OTHER CLASSES
|
|
|
|
|
|
class WebPage(CoderedWebPage):
|
|
|
"""
|
|
|
General use page with featureful streamfield and SEO attributes.
|
|
|
- Template renders all Navbar and Footer snippets in existence.
|
|
|
"""
|
|
|
+
|
|
|
class Meta:
|
|
|
- verbose_name = 'Web Page'
|
|
|
+ verbose_name = "Web Page"
|
|
|
+
|
|
|
+ template = "coderedcms/pages/web_page.html"
|
|
|
|
|
|
- template = 'coderedcms/pages/web_page.html'
|
|
|
|
|
|
|
|
|
Before we begin adding our fields for our new page models, we should add the page class, meta class,
|
|
@@ -141,46 +96,47 @@ and template information for our pages.
|
|
|
|
|
|
* We our extending the ``CoderedWebPage`` model which is why it is wrapped in parentheses after we name our page model.
|
|
|
|
|
|
-* We are indicating that Cupcake pages are sub-pages of the Cupcake Landing Page.
|
|
|
+* We are indicating that Product pages are sub-pages of the Product Landing Page.
|
|
|
|
|
|
-* We are specifying the template files that the page models should use, which should also be created in our ``templates\website\pages`` folder.
|
|
|
+* We are specifying the template files the page models use, these need to be created in the ``templates\website\pages`` folder.
|
|
|
|
|
|
Add this code below the other page models:
|
|
|
|
|
|
.. code:: python
|
|
|
|
|
|
- class CupcakesIndexPage(CoderedWebPage):
|
|
|
+ class ProductIndexPage(CoderedWebPage):
|
|
|
"""
|
|
|
- Landing page for Cupcakes
|
|
|
+ Landing page for Products
|
|
|
"""
|
|
|
class Meta:
|
|
|
- verbose_name = "Cupcakes Landing Page"
|
|
|
+ verbose_name = "Product Landing Page"
|
|
|
|
|
|
# Override to specify custom index ordering choice/default.
|
|
|
- index_query_pagemodel = 'website.CupcakesPage'
|
|
|
+ index_query_pagemodel = 'website.ProductPage'
|
|
|
|
|
|
- # Only allow CupcakesPages beneath this page.
|
|
|
- subpage_types = ['website.CupcakesPage']
|
|
|
+ # Only allow ProductPages beneath this page.
|
|
|
+ subpage_types = ['website.ProductPage']
|
|
|
|
|
|
- template = 'website/pages/cupcakes_index_page.html'
|
|
|
+ template = 'website/pages/product_index_page.html'
|
|
|
|
|
|
|
|
|
- class CupcakesPage(CoderedWebPage):
|
|
|
+ class ProductPage(CoderedWebPage):
|
|
|
"""
|
|
|
- Custom page for individual cupcakes
|
|
|
+ Custom page for individual products
|
|
|
"""
|
|
|
|
|
|
class Meta:
|
|
|
- verbose_name = "Cupcakes Page"
|
|
|
+ verbose_name = "Product Page"
|
|
|
|
|
|
- # Only allow this page to be created beneath an CupcakesIndexPage.
|
|
|
- parent_page_types = ['website.CupcakesIndexPage']
|
|
|
+ # Only allow this page to be created beneath an ProductIndexPage.
|
|
|
+ parent_page_types = ['website.ProductIndexPage']
|
|
|
|
|
|
- template = "website/pages/cupcakes_page.html"
|
|
|
+ template = "website/pages/product_page.html"
|
|
|
|
|
|
|
|
|
-At the top of each ``.html`` template page, we want to add these tags so that we have a basic functioning
|
|
|
-template prepared:
|
|
|
+* Create the template pages ``product_page.html`` and ``product_index_page.html`` in the ``templates\website\pages`` folder.
|
|
|
+
|
|
|
+* At the top of these template pages, add these tags to have basic functioning template:
|
|
|
|
|
|
.. code:: Django
|
|
|
|
|
@@ -188,9 +144,9 @@ template prepared:
|
|
|
{% load wagtailcore_tags wagtailimages_tags coderedcms_tags %}
|
|
|
|
|
|
|
|
|
-Now we can turn our attention back to our page models, specifically the CupcakesPage.
|
|
|
-Since the name of the cupcake could just be the title of the page, we don't need to add a custom field
|
|
|
-for that information. We do, however, need a few fields.
|
|
|
+Now we can turn our attention back to our page models, specifically the ProductPage.
|
|
|
+In this example the the name of the product will be the title of the Page.
|
|
|
+We need to add other fields to be be in alignment with the outline we looked at earlier.
|
|
|
|
|
|
.. code:: python
|
|
|
|
|
@@ -201,23 +157,24 @@ for that information. We do, however, need a few fields.
|
|
|
from wagtail.images import get_image_model_string
|
|
|
from wagtail.images.edit_handlers import ImageChooserPanel
|
|
|
|
|
|
+ # Update the product page with these fields
|
|
|
|
|
|
- class CupcakesPage(CoderedWebPage):
|
|
|
+ class ProductPage(CoderedWebPage):
|
|
|
"""
|
|
|
- Custom page for individual cupcakes
|
|
|
+ Custom page for individual products
|
|
|
"""
|
|
|
|
|
|
class Meta:
|
|
|
- verbose_name = "Cupcakes Page"
|
|
|
+ verbose_name = "Product Page"
|
|
|
|
|
|
- # Only allow this page to be created beneath an CupcakesIndexPage.
|
|
|
- parent_page_types = ['website.CupcakesIndexPage']
|
|
|
+ # Only allow this page to be created beneath an ProductIndexPage.
|
|
|
+ parent_page_types = ['website.ProductIndexPage']
|
|
|
|
|
|
- template = "website/pages/cupcakes_page.html"
|
|
|
+ template = "website/pages/product_page.html"
|
|
|
|
|
|
- # Cupcakes Page model fields
|
|
|
+ # Product Page model fields
|
|
|
description = RichTextField(
|
|
|
- verbose_name="Cupcake Description",
|
|
|
+ verbose_name="Product Description",
|
|
|
null=True,
|
|
|
blank=True,
|
|
|
default=""
|
|
@@ -228,85 +185,91 @@ for that information. We do, however, need a few fields.
|
|
|
blank=True,
|
|
|
on_delete=models.SET_NULL,
|
|
|
related_name='+',
|
|
|
- verbose_name='Cupcake Photo',
|
|
|
- )
|
|
|
- DAYS_CHOICES = (
|
|
|
- ("Weekends Only", "Weekends Only"),
|
|
|
- ("Monday-Friday", "Monday-Friday"),
|
|
|
- ("Tuesday/Thursday", "Tuesday/Thursday"),
|
|
|
- ("Seasonal", "Seasonal"),
|
|
|
- )
|
|
|
- days_available = models.CharField(
|
|
|
- choices = DAYS_CHOICES,
|
|
|
- max_length=20,
|
|
|
- default=""
|
|
|
+ verbose_name='Product Photo',
|
|
|
)
|
|
|
+ need_prescription = models.BooleanField(default=True)
|
|
|
|
|
|
# Add custom fields to the body
|
|
|
body_content_panels = CoderedWebPage.body_content_panels + [
|
|
|
FieldPanel("description"),
|
|
|
FieldPanel("photo"),
|
|
|
- FieldPanel("days_available"),
|
|
|
+ FieldPanel("need_prescription"),
|
|
|
]
|
|
|
|
|
|
|
|
|
**What's happening?**
|
|
|
|
|
|
-Okay, we had to add some imports at the top to be able to use these field types in our model.
|
|
|
+We had to add some imports at the top to be able to use these field types in our model.
|
|
|
If we try to makemigrations/migrate without having these imported, it will show an error.
|
|
|
|
|
|
-Next, we added the fields we need with the field types that tell it how to function. Our description
|
|
|
-will be a RichTextField which is essentially a text box that allows formatting. Then our photo needs to be
|
|
|
-able to be associated with the page as well as be uploaded via an ImageChooserPanel -- the popup we get when
|
|
|
-we want to add a photo in the CMS.
|
|
|
+Next, we added the necessary fields and their field types that specify functionality.
|
|
|
|
|
|
-Finally, we added a field for choosing which days the cupcake is available and we made this a dropdown choice
|
|
|
-panel. We had to set the choices first, then include the choices in our field selector.
|
|
|
+* ``description`` is a RichTextField (essentially a text box) that allows formatting.
|
|
|
+* ``photo`` uses a ForeignKey to reference the image_mode. This allows an image to be uploaded via an ImageChooserPanel -- the popup we get when we want to add a photo in the CMS.
|
|
|
+* ``need_prescription`` is a Boolean value that tells us if the product requires a prescription.
|
|
|
+* ``body_content_panels`` is defining which page builder blocks the editing screen should show. (In this instance, it's using the wagtail-CRX standard blocks, plus the custom fields in the model.)
|
|
|
|
|
|
-At the bottom of our model, we are telling it to allow for the standard CMS page builder blocks as well as our custom
|
|
|
-fields.
|
|
|
+These changes to the models have to be migrated in the the database. To do so:
|
|
|
+
|
|
|
+* You need to have an active virtual environment. (See :ref:`installation` notes for help)
|
|
|
+* (if running) Stop your server with ``control + c``
|
|
|
+* Run ``python manage.py makemigrations`` (The makemigrations command uses the models specify changes that are going to be made to the database)
|
|
|
+* Run ``python manage.py migrate`` (The migrate command makes those changes)
|
|
|
|
|
|
-Now we can run ``python manage.py makemigrations website`` and ``python manage.py migrate`` to test our work.
|
|
|
It should migrate successfully. (If not, read what the error says and fix it. A typo can cause huge problems!)
|
|
|
|
|
|
-Run the server again with ``python manage.py runserver`` to see how it looks in your CMS admin.
|
|
|
+* Run the server with ``python manage.py runserver`` to see how it looks in your CMS admin.
|
|
|
+
|
|
|
+You should now see Product Landing Page as a page choice.
|
|
|
+
|
|
|
+.. figure:: img/A02/plp_as_child.jpeg
|
|
|
+ :alt: product landing page in the page selector
|
|
|
+
|
|
|
+To be inline with our CRX-pharma design (from the getting started tutorial), we are going to add a **Product Landing Page** as a child of the "Our Products" page **Home > Our Products**.
|
|
|
+Hopefully, if you followed the tutorial this is a pretty basic operation. As a quick "refresher":
|
|
|
+
|
|
|
+* Click **Pages** in the side menu
|
|
|
+* Use the arrow and click on the "Our Product Page". ("If you don't have one, just use Home")
|
|
|
+* This opens the page management screen. Click **Add child page**
|
|
|
+* Choose page type **Product Landing Page**
|
|
|
+* Give it a title (Direct to Consumer Products)
|
|
|
+* (optional) Add a cover image.
|
|
|
|
|
|
-You should now see Cupcake Landing Page as a child page choice under Home page. Choose this, add a title and
|
|
|
-publish it. The page does not have a template made; however, it uses the basic CodeRed Web Page so it will display
|
|
|
-something.
|
|
|
+.. figure:: img/A02/plp_editor.jpeg
|
|
|
+ :alt: product landing page editor
|
|
|
|
|
|
-Now you can add Cupcake Pages, which are sub-pages of the Cupcake Landing Page. While the fields for this page
|
|
|
-do not currently show up on the published page, you can add content in the editor mode.
|
|
|
+* **Save** and **Publish**
|
|
|
|
|
|
.. note::
|
|
|
- We have to create a custom page template to display the custom fields on the published page.
|
|
|
+ We still have to work on the templates for both Product Page and Product Landing Page. They are placeholders to prevent Django from throwing errors.
|
|
|
+
|
|
|
+
|
|
|
+Let's add a Product Page to the project:
|
|
|
+
|
|
|
+* Click **Add child page** on the the Product Landing Page we just published (titled "Direct to Consumer Products")
|
|
|
+
|
|
|
+.. figure:: img/A02/pp_editor.jpeg
|
|
|
+ :alt: product page editor
|
|
|
+
|
|
|
+Look at the fields. The page editor has the standard "CoderedWebPage" fields (Title, Cover image, and Body) plus the ones we added to the model (Product Description, Product Photo, and Need prescription).
|
|
|
+
|
|
|
+* Make 3 or 4 Product pages.
|
|
|
+* Remember to **Save** and **Publish** each page.
|
|
|
|
|
|
|
|
|
Building our custom page templates
|
|
|
----------------------------------
|
|
|
|
|
|
-Since our models are working and we can add content to the fields, we can begin creating our custom page
|
|
|
-template. Navigate to the ``cupcakes_page.html`` file in your project's templates folder. We added the basic
|
|
|
-page tags at the top of the page earlier. In case you need to add them, they are:
|
|
|
+Navigate to ``templates\website\pages\product_page.html``. This code was added earlier:
|
|
|
|
|
|
.. code::
|
|
|
|
|
|
{% extends "coderedcms/pages/web_page.html" %}
|
|
|
{% load wagtailcore_tags wagtailimages_tags coderedcms_tags %}
|
|
|
|
|
|
-Now we want to tell the page to not display the page's title where the cover image would be if there is no cover
|
|
|
-image (because we plan to use the page's title aka the cupcake name elsewhere on the page).
|
|
|
-
|
|
|
-The standard CodeRed Web Page template has an ``{% if %} {% else %}`` statement regarding cover images that says to show the page title when a cover image
|
|
|
-is not available. We will add that same code to our page but remove the ``else`` statement so that it does nothing when a cover image is not available.
|
|
|
-
|
|
|
-We will also set up the basic layout for our page: a two half-sized columns in a row. To pull in our field data,
|
|
|
-we reference the page and then the field, like this ``{{page.title}}`` or ``{{page.description}}``.
|
|
|
+These page tags extend the wagtail-CRX page and gives us access to the data in store in the database for each page.
|
|
|
|
|
|
-For the image, we specify what size it should be and give it a shorter reference name for the variable.
|
|
|
-
|
|
|
-We added a few Bootstrap classes and custom classes to change the padding a little and some text colors, as well
|
|
|
-as add a border around the image that is centered within the column.
|
|
|
+Here is our whole template:
|
|
|
|
|
|
**Our template code:**
|
|
|
|
|
@@ -315,33 +278,46 @@ as add a border around the image that is centered within the column.
|
|
|
{% extends "coderedcms/pages/web_page.html" %}
|
|
|
{% load wagtailcore_tags wagtailimages_tags coderedcms_tags %}
|
|
|
|
|
|
+
|
|
|
{% block content_pre_body %}
|
|
|
- {% if self.cover_image %}
|
|
|
- {% image page.cover_image fill-2000x1000 as cover_image %}
|
|
|
- <div class="jumbotron jumotron-fluid" style="height:400px;background-image:url({{cover_image.url}});background-repeat:no-repeat; background-size:cover; background-position:center center;">
|
|
|
+ {% if self.cover_image %}
|
|
|
+ {% image page.cover_image fill-1600x900 format-webp as cover_image %}
|
|
|
+ <div class="hero-bg mb-5" style="background-image:url({{cover_image.url}});">
|
|
|
+ <div class="hero-fg">
|
|
|
+ <div class="container text-center">
|
|
|
+ <h1 class="text-white text-shadow">{{page.title}}</h1>
|
|
|
</div>
|
|
|
- {% endif %}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ {% endif %}
|
|
|
{% endblock %}
|
|
|
|
|
|
-
|
|
|
{% block content_body %}
|
|
|
<div class="block-row">
|
|
|
<div class="container-fluid">
|
|
|
<div class="row m-4">
|
|
|
<div class="col-lg-6">
|
|
|
{% if page.photo %}
|
|
|
- {% image page.photo fill-300x300 as cupcake %}
|
|
|
+ {% image page.photo fill-400x400 as product %}
|
|
|
<div class="text-center">
|
|
|
- <img class="border-cherry" src="{{cupcake.url}}" alt="photo of {{page.title}}">
|
|
|
+ <img src="{{product.url}}" alt="photo of {{page.title}}">
|
|
|
</div>
|
|
|
{% endif %}
|
|
|
</div>
|
|
|
<div class="col-lg-6">
|
|
|
<div class="py-lg-5">
|
|
|
- <h2>{{page.title}}</h2>
|
|
|
- <lead class="text-cherry">{{page.days_available}}</lead>
|
|
|
+ {% if self.cover_image %}
|
|
|
+ {% else %}
|
|
|
+ <h2 class="text-primary fw-bold fs-1 mb-2">{{page.title}}</h2>
|
|
|
+ {% endif %}
|
|
|
+
|
|
|
{% if page.description %}
|
|
|
- <p>{{page.description|richtext}}</p>
|
|
|
+ {{page.description|richtext}}
|
|
|
+ {% endif %}
|
|
|
+ {% if page.need_prescription %}
|
|
|
+ <div class="fs-5"> Call your doctor to see if {{page.title}} is right for you!</div>
|
|
|
+ {% else %}
|
|
|
+ <div class="fs-5"> No Prescription Needed!</div>
|
|
|
{% endif %}
|
|
|
</div>
|
|
|
</div>
|
|
@@ -350,48 +326,75 @@ as add a border around the image that is centered within the column.
|
|
|
</div>
|
|
|
{% endblock %}
|
|
|
|
|
|
+The ``{% block content_pre_body %}`` tag overrides part of the standard template. It uses conditional logic {% if %} to render the page title {{page.title}} in the header if the user
|
|
|
+adds a cover image. If they don't, the page.title renders in {% block content_body %}. There is a basic two column, with the image on the left and a description on the right. It also uses an
|
|
|
+{% if %} {% else %} statement with the {{page.need_prescription}} to render different text based on if the product needs a prescription.
|
|
|
|
|
|
-We added some content for a cupcake page in the CMS and published it.
|
|
|
+There is a lot to cover in Django templating. Check out the docs for more info `Django Templates <https://docs.djangoproject.com/en/4.1/topics/templates/>`_
|
|
|
|
|
|
-Let's take a look.
|
|
|
+Here's the same template with and without a cover image:
|
|
|
|
|
|
-.. figure:: img/cupcake_page_published.png
|
|
|
- :alt: Our customized cupcake page so far
|
|
|
+.. figure:: img/A02/pp_preview.jpeg
|
|
|
+ :alt: product page preview with out cover image
|
|
|
|
|
|
- Our customized cupcake page so far
|
|
|
+No cover image so the page title renders in the body.
|
|
|
|
|
|
+.. figure:: img/A02/pp_preview2.jpeg
|
|
|
+ :alt: product page preview with cover image
|
|
|
|
|
|
-It works! Continue to add cupcake pages until you have a decent amount of them --
|
|
|
-five or so would be good.
|
|
|
+With the cover image and the title is centered with a bootstrap class "text-center" in the template.
|
|
|
|
|
|
-Building the Cupcake Landing Page
|
|
|
+Building the Product Landing Page
|
|
|
---------------------------------
|
|
|
|
|
|
While we could simply use the the default "Show Child Pages" option for the page, a list of links
|
|
|
-is rather boring. We also want the page to automatically update whenever we add a new cupcake to save us lots of time
|
|
|
-and trouble. How can we dynamically update our Cupcake Landing Page?
|
|
|
+is rather boring. We also want the page to automatically update whenever we add a new product to save us lots of time
|
|
|
+and trouble. He is our template:
|
|
|
|
|
|
.. code:: Django
|
|
|
|
|
|
{% extends "coderedcms/pages/web_page.html" %}
|
|
|
{% load wagtailcore_tags wagtailimages_tags coderedcms_tags %}
|
|
|
|
|
|
- {% block index_content %}
|
|
|
+ {% block content_pre_body %}
|
|
|
+ {% if self.cover_image %}
|
|
|
+ {% image page.cover_image fill-1600x900 format-webp as cover_image %}
|
|
|
+ <div class="hero-bg mb-5" style="background-image:url({{cover_image.url}});">
|
|
|
+ <div class="hero-fg">
|
|
|
+ <div class="d-flex justify-content-center">
|
|
|
+ <h1 class="text-shadow text-white">{{page.title}}</h1>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ {% else %}
|
|
|
<div class="container">
|
|
|
- <div class="row d-flex">
|
|
|
- {% for cupcake in page.get_children.specific %}
|
|
|
- <div class="col m-3">
|
|
|
- <div class="card border-cherry" style="width: 18rem;">
|
|
|
- {% if cupcake.photo %}
|
|
|
- {% image cupcake.photo fill-300x300 as cupcake_photo %}
|
|
|
- <a href="{{cupcake.url}}">
|
|
|
- <img class="card-img-top w-100" src="{{cupcake_photo.url}}" alt="{{cupcake.title}}">
|
|
|
+ <h1>{{page.title}}</h1>
|
|
|
+ </div>
|
|
|
+ {% endif %}
|
|
|
+ {% endblock %}
|
|
|
+
|
|
|
+
|
|
|
+ {% block index_content %}
|
|
|
+ <div class="container mb-5">
|
|
|
+ <div class="row row-cols-2 row-cols-md-3 row-cols-xl-4">
|
|
|
+ {% for product in page.get_children.specific %}
|
|
|
+ <div class="col text-center">
|
|
|
+ <div class="card h-100">
|
|
|
+ {% if product.photo %}
|
|
|
+ {% image product.photo fill-300x300 as product_photo %}
|
|
|
+ <a href="{{product.url}}">
|
|
|
+ <img class="card-img-top w-100" src="{{product_photo.url}}" alt="{{product.title}}">
|
|
|
</a>
|
|
|
{% endif %}
|
|
|
<div class="card-body">
|
|
|
<div class="card-text">
|
|
|
- <h3><a class="text-cherry" href="{{cupcake.url}}">{{cupcake.title}}</a></h3>
|
|
|
- <p class="lead">{{cupcake.days_available}}</p>
|
|
|
+ <h5><a href="{{product.url}}">{{product.title}}</a></h5>
|
|
|
+ {{product.description|richtext}}
|
|
|
+ {% if page.need_prescription %}
|
|
|
+ <p> Call your doctor to see if {{page.title}} is right for you!</p>
|
|
|
+ {% else %}
|
|
|
+ <p> No Prescription Needed!</p>
|
|
|
+ {% endif %}
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -401,18 +404,17 @@ and trouble. How can we dynamically update our Cupcake Landing Page?
|
|
|
</div>
|
|
|
{% endblock %}
|
|
|
|
|
|
-
|
|
|
**What's happening?**
|
|
|
|
|
|
-We are using a ``{% block index_content %}`` and a ``{% for cupcake in page.get_children.specific %}`` loop that pulls
|
|
|
-in content from the child/sub-pages. Our new variable for the sub-pages is ``cupcake``, so we reference the fields like so:
|
|
|
-``{{cupcake.title}}``. In the CMS we want to make show that "Show Child Pages" is NOT selected because it will just show
|
|
|
-the list of page links in addition to our custom cards. This is what our published landing page looks like now:
|
|
|
+We are using a ``{% block index_content %}`` and a ``{% for product in page.get_children.specific %}`` loop that pulls
|
|
|
+in content from the child/sub-pages. Our new variable for the sub-pages is ``product``, so we reference the fields like so:
|
|
|
+``{{product.title}}``. The different products are in cards in card-grid, size with different bootstrap breakpoints.
|
|
|
+
|
|
|
+This is what our published landing page looks like now:
|
|
|
|
|
|
-.. figure:: img/cupcake_landing_published.png
|
|
|
- :alt: Our customized landing cupcake page so far
|
|
|
+.. figure:: img/A02/plp_preview.jpeg
|
|
|
+ :alt: product landing page preview
|
|
|
|
|
|
- Our customized cupcake landing page dynamically pulling in child pages as cards
|
|
|
+Product Landing Page on a large screen.
|
|
|
|
|
|
|
|
|
-Now we can keep customizing our templates until we get the design that we want.
|