Adding non-Mezzanine apps to Mezzanine menu

1,524 views
Skip to first unread message

Neum

unread,
May 7, 2012, 11:38:12 AM5/7/12
to mezzani...@googlegroups.com
I've added Mezzanine to an existing Django project and its working great, except I don't see a simple way to add outside app URL's to the menu in Mezzanine. Just to be clear I'm talking about the front end menu of a site. In working with some other Django CMS's I noticed they have a redirect option when building out pages that allows you to redirect a given page over to an outside app and still build the navigation entirely in the CMS (django-cms). I don't see anything like that in Mezzanine though. Do I need to override each template in Mezzanine to be able to add my custom apps to the Mezzanine built menu? Is there a best way to do this? If I was building from scratch I would just build my apps as custom content types but I'd rather not have to change all of that now. Thanks.

Stephen McDonald

unread,
May 7, 2012, 4:39:35 PM5/7/12
to mezzani...@googlegroups.com
Firstly, the current approach is to just add a page with a URL that matches the urlpattern for the app. Mezzanine's blog app works this way. 

If you have access to the code for the app, you can also wrap its views in a decorator that will add the page to the context so you can use its data in the template. This is about the only integration you need to get it fully working, but it's obviously a problem if you don't have access to the code, eg a third party app. I believe with Django CMS you need to create a class that maps the page to the urlpatterns. I think it's called a CMS plugin or something but I'm not across the details, the point is that with both project, some form of manual hookup is required. 

I've been thinking about this problem ever since Mezzanine was started but never really had a good idea until now as to how to solve it. So my idea is that we take the current view function for pages, and turn it into middleware. It would behave exactly the same way - making use of Mezzanine's page processors, slug based templates, etc, it'd just happen in the middleware layer. This way pages can be loaded for any view, third-party app or otherwise. This way all you ever need to do to integrate app urlpatterns with pages in the page tree is as I first described, add the page with a URL matching the pattern, and everything just works - the app's view will be used, and it'll also have all the page functionality, without any special pairing required. We could even go as far as to modify the URL field for pages and have the ability to select from a drop-down populated by urlpatterns in the project, to make it even more seamless (rather than having to know the app's urlpattern in advance).

Thoughts?

On Tue, May 8, 2012 at 1:38 AM, Neum <ne...@pageworthy.com> wrote:
I've added Mezzanine to an existing Django project and its working great, except I don't see a simple way to add outside app URL's to the menu in Mezzanine. Just to be clear I'm talking about the front end menu of a site. In working with some other Django CMS's I noticed they have a redirect option when building out pages that allows you to redirect a given page over to an outside app and still build the navigation entirely in the CMS (django-cms). I don't see anything like that in Mezzanine though. Do I need to override each template in Mezzanine to be able to add my custom apps to the Mezzanine built menu? Is there a best way to do this? If I was building from scratch I would just build my apps as custom content types but I'd rather not have to change all of that now. Thanks.



--
Stephen McDonald
http://jupo.org

Josh Cartmell

unread,
May 8, 2012, 12:14:56 PM5/8/12
to mezzani...@googlegroups.com
I think that middleware sounds like a good approach Steve. If we go with the dropdown for URLs does that mean we lose the ability to manually override the slug of a page?  I find the ability to manually override useful from time to time.

Stephen McDonald

unread,
May 8, 2012, 4:19:45 PM5/8/12
to mezzani...@googlegroups.com
No, manually entering a URL is definitely a core feature. You'd get a field that looked like:

Enter a URL (or leave blank to have it generated), OR choose from the urlpattern drop-down to point to an existing app.

The values in the drop-down would be the names of the urlpatterns in a friendly form, eg blog_list would become "Blog List".

Josh Cartmell

unread,
May 8, 2012, 4:40:29 PM5/8/12
to mezzani...@googlegroups.com
Ok good, that sounds good to me then.

Stephen McDonald

unread,
May 10, 2012, 7:11:39 AM5/10/12
to mezzani...@googlegroups.com
I've added this change here:


Made a quick attempt at the drop-down field for selecting an existing urlpattern, but it looks like the effort mightn't be worth the trouble, so I'm gonna leave that one for now.

So as it stands there's no real visible change - page loading, page processors and page.login_required check are now in the middleware. Template selection and handling 404s still live in the page view. So it's now possible to point a page at any urlpattern and the page will exist in the template context, so integrating third-party apps into the page menu is a no brainer.

Josh Cartmell

unread,
May 10, 2012, 12:36:02 PM5/10/12
to mezzani...@googlegroups.com
With these changes in mind would it be worth making another core content type that would basically only be a slug?  Many third party apps aren't going to care about what it stored in the db with the Page and the only real desire is to have it in the menus.

It might also be nice to have a page type which just stores a URL to an external site so that you could have links in your menus to an external blog, shop, portfolio etc...  Ideally people would use the Mezzanine blog and Cartridge shop but sometimes people aren't ready to make that jump if they already have something established.

These may be outside the scope of Mezzanine and up to the developer to make their own custom content types but they were thoughts that struck me as I re-read this.

Josh Cartmell

unread,
May 10, 2012, 4:22:41 PM5/10/12
to mezzani...@googlegroups.com
I just thought about his but creating a content type that simply redirects to an outside URL would also be nice so that you could segregate a blog or shop to a separate subdomain.  So you could have example.com, blog.example.com and shop.example.com.  Using the new multi tenancy they could all actually be served by the same django instance.

Stephen McDonald

unread,
May 10, 2012, 4:52:50 PM5/10/12
to mezzani...@googlegroups.com
Great idea - I imagine it'd be a very common requirement and shouldn't take much effort. Just need to figure out how to strip down its admin to just the URL field.

Gary Reynolds

unread,
May 10, 2012, 4:56:53 PM5/10/12
to mezzani...@googlegroups.com
On Friday, 11 May 2012 at 6:52 AM, Stephen McDonald wrote:
Great idea - I imagine it'd be a very common requirement and shouldn't take much effort. Just need to figure out how to strip down its admin to just the URL field.

Custom ModelForm with a Meta.fields attribute?

Stephen McDonald

unread,
May 10, 2012, 5:01:51 PM5/10/12
to mezzani...@googlegroups.com
Yeah that might work. I was initially thinking it might be able to all happen on its admin class.

Josh Cartmell

unread,
May 10, 2012, 5:40:10 PM5/10/12
to mezzani...@googlegroups.com
This may be assumed/implied but I think it would still be nice to keep the status and published from and expires on in addition to the url/slug as people may not want a particular link to show up till or after a certain date.  It would also allow consistent control of menu presentation across all content types which I think increases user comfort.

Stephen McDonald

unread,
May 10, 2012, 5:43:22 PM5/10/12
to mezzani...@googlegroups.com

Yeah definitely

Stephen McDonald

unread,
May 10, 2012, 7:01:04 PM5/10/12
to mezzani...@googlegroups.com
I've got this all working - will push up later today.

Stephen McDonald

unread,
May 11, 2012, 7:23:38 AM5/11/12
to mezzani...@googlegroups.com
And here it is:


This meant changing how the urls are referenced in each of the page menu templates. They now use {{ page.get_absolute_url }} instead of {% url page page.slug %}

Josh Cartmell

unread,
May 11, 2012, 12:07:17 PM5/11/12
to mezzani...@googlegroups.com
Great! A link could reference an external page or an internal one depending on what you put in the slug, is that correct?

So http://blog.example.com would point away vs /non/mezzanine/app/ could point to a non-Mezzanine django app.

I thought it might be helpful to write that down in case anyone else comes across this thread.

Stephen McDonald

unread,
May 11, 2012, 12:12:07 PM5/11/12
to mezzani...@googlegroups.com
Yep that's right.

Neum

unread,
May 25, 2012, 5:22:19 PM5/25/12
to Mezzanine Users
Just as a follow up to my last post I realized from this new post
https://groups.google.com/group/mezzanine-users/browse_thread/thread/7f9b1cad8649dfec
that I should be using a "rich text page" and not a link to create
these. These do work correctly in the navigation and the links
correctly as well as long as no slashes are used. These pages are not
editable in the admin however for me either, not sure if its just a
local bug for me or not. Thanks!!!

On May 11, 10:12 am, Stephen McDonald <st...@jupo.org> wrote:
> Yep that's right.
>
>
>
>
>
>
>
>
>
> On Sat, May 12, 2012 at 2:07 AM, Josh Cartmell <joshcar...@gmail.com> wrote:
> > Great! A link could reference an external page or an internal one
> > depending on what you put in the slug, is that correct?
>
> > Sohttp://blog.example.comwould point away vs /non/mezzanine/app/ could
> > point to a non-Mezzanine django app.
>
> > I thought it might be helpful to write that down in case anyone else comes
> > across this thread.
>
> > On Fri, May 11, 2012 at 4:23 AM, Stephen McDonald <st...@jupo.org> wrote:
>
> >> And here it is:
>
> >>https://github.com/stephenmcd/mezzanine/commit/32c49ee72b4813a03f57cf...
>
> >> This meant changing how the urls are referenced in each of the page menu
> >> templates. They now use {{ page.get_absolute_url }} instead of {% url page
> >> page.slug %}
>
> >> On Fri, May 11, 2012 at 9:01 AM, Stephen McDonald <st...@jupo.org> wrote:
>
> >>> I've got this all working - will push up later today.
>
> >>> On Fri, May 11, 2012 at 7:43 AM, Stephen McDonald <st...@jupo.org>wrote:
>
> >>>> Yeah definitely

Neum

unread,
May 25, 2012, 5:05:41 PM5/25/12
to Mezzanine Users
Thank you Stephen for getting that put in so quickly. Mezzanine is
awesome! I updated to the trunk yesterday and in local development
(Postgres) I'm seeing some weird behavior with implementing links to
my outside apps. If the slug for the link I put in has no slashes
(which I believe is the convention for other pages) then the link
behaves like a relative URL that always appends the URL onto the URL
of the page you are currently on. So if you visit the example.com/app-
url/inner-url/ and then click the link for the app in the menu you'll
get example.com/app-url/inner-url/app-url/ but more importantly the
ability to edit the link or delete it in the admin disappears!

If I add the link with a beginning and trailing slash on the slug then
it works correctly but the active menu styling in the navbar no longer
works, not sure why that is. If it has the beginning slash then you
can edit it in the admin and delete it just fine.

On a side note breadcrumbs on the external apps inner pages (once
you're past the link page) don't work. I'm sure that's because the
pages app doesn't know about them but I'm wondering if there might be
a way to traverse back through the outside app URL's to add them to
breadcrumbs as well? For now I'm just going to turn off breadcrumbs,
but it would be nice to be able to add them in the future somehow.

Thanks again for the great work. I'm going to start working with
Mezzanine almost exclusively now, its seriously that good.


On May 11, 10:12 am, Stephen McDonald <st...@jupo.org> wrote:
> Yep that's right.
>
>
>
>
>
>
>
>
>
> On Sat, May 12, 2012 at 2:07 AM, Josh Cartmell <joshcar...@gmail.com> wrote:
> > Great! A link could reference an external page or an internal one
> > depending on what you put in the slug, is that correct?
>
> > Sohttp://blog.example.comwould point away vs /non/mezzanine/app/ could
> > point to a non-Mezzanine django app.
>
> > I thought it might be helpful to write that down in case anyone else comes
> > across this thread.
>
> > On Fri, May 11, 2012 at 4:23 AM, Stephen McDonald <st...@jupo.org> wrote:
>
> >> And here it is:
>
> >>https://github.com/stephenmcd/mezzanine/commit/32c49ee72b4813a03f57cf...
>
> >> This meant changing how the urls are referenced in each of the page menu
> >> templates. They now use {{ page.get_absolute_url }} instead of {% url page
> >> page.slug %}
>
> >> On Fri, May 11, 2012 at 9:01 AM, Stephen McDonald <st...@jupo.org> wrote:
>
> >>> I've got this all working - will push up later today.
>
> >>> On Fri, May 11, 2012 at 7:43 AM, Stephen McDonald <st...@jupo.org>wrote:
>
> >>>> Yeah definitely

Stephen McDonald

unread,
Jun 3, 2012, 1:02:00 AM6/3/12
to mezzani...@googlegroups.com
I've made a few changes which I think resolve all the problems you described.

The page highlighting and breadcrumbs are all based upon helpers that are set in Page.set_menu_helpers. They set things like "is the page a sibling of the current" and "is the page an ascendant of the current". All of this was based on comparions with the actual current URL, which when you starting doing (seemingly strange things) with custom URLs in child pages that don't match the actual parent/child hierarchy of the pages, falls apart tragically. So I've rewritten that area of the code to use the actual page object being viewed, instead of the current URL, so all the comparisons work, and you can have pages in the tree with URLs that break from the URLs of their parents and children, and it all works correctly now:


The other main issue was using the Link content type for internal URLs. As you mentioned, the implied correct way to use URLs was without an initial slash, as all the other page types do this by default. Then pages that use the Link model don't actually use a urlpattern to return their URL, they just return their slug. So I've changed the get_absolute_url method where this happens to ensure Link pages without an initial slash always return an absolute URL (with a trailing slash). Technically you can also use an initial slash with them as well, and the first fix mentioned above means they won't break anything, but the implied way is without it, so now that works:


I've also relaxed the conditions on deleting and adding children to pages that are overridden, that is, those pointing to a non-page urlpattern, as this is something that seems to keep getting in people's way:

Message has been deleted

Stephen McDonald

unread,
Oct 23, 2012, 3:39:29 PM10/23/12
to mezzani...@googlegroups.com
Hello, the docs should have you covered:

On Mon, Oct 22, 2012 at 7:43 AM, nizar chaouachi <nizar.c...@gmail.com> wrote:
Hi Mr,

I am new to django, would you please share with me how integrate mezzanine to an existing Django App

 
or and vice-versa

 

Thanks


Le lundi 7 mai 2012 16:38:12 UTC+1, Neum Schmickrath a écrit :
I've added Mezzanine to an existing Django project and its working great, except I don't see a simple way to add outside app URL's to the menu in Mezzanine. Just to be clear I'm talking about the front end menu of a site. In working with some other Django CMS's I noticed they have a redirect option when building out pages that allows you to redirect a given page over to an outside app and still build the navigation entirely in the CMS (django-cms). I don't see anything like that in Mezzanine though. Do I need to override each template in Mezzanine to be able to add my custom apps to the Mezzanine built menu? Is there a best way to do this? If I was building from scratch I would just build my apps as custom content types but I'd rather not have to change all of that now. Thanks.
Reply all
Reply to author
Forward
0 new messages