Loading menu component with JavaScript and still having the CmsEditMenu button inside the cms

123 views
Skip to first unread message

Gangel Dávid

unread,
Jul 29, 2015, 10:07:48 AM7/29/15
to Hippo Community
Hi,

I'm a bit stuck.

I would like to have a menu on the home page which is loaded by javascript.
That's fine it loads on the site without issues.
But at the same time I don't have the CmsEditMenu button inside the channel editor.

How can I make it working again?

s.muco

unread,
Jul 29, 2015, 10:27:38 AM7/29/15
to Hippo Community, gan...@gmail.com
Hi,
please read the documentation in [1] on how to add a menu button inside your jsp/ftl. Hope it helps
Regards
Saimir

Gangel Dávid

unread,
Jul 29, 2015, 10:28:54 AM7/29/15
to Hippo Community, s.m...@onehippo.com
Hi,

I know this and I fulfill the pre-requirements.

Niels van Kampenhout

unread,
Jul 29, 2015, 1:09:21 PM7/29/15
to Hippo Community
Can you share your Freemarker or JSP template? It's hard for us to
guess what is going wrong if we don't know your code.
Also, do you get any exceptions (Java or Javascript)?

Basically if you have a menu object and use the hst:cmseditmenu tag,
it should work. How the menu itself is rendered doesn't really matter.

Things to check:
Is the menu object perhaps null?
Is the button perhaps there in the HTML but not visible because of
some CSS issue?
> --
> Hippo Community Group: The place for all discussions and announcements about
> Hippo CMS (and HST, repository etc. etc.)
>
> To post to this group, send email to hippo-c...@googlegroups.com
> RSS:
> https://groups.google.com/group/hippo-community/feed/rss_v2_0_msgs.xml?num=50
> ---
> You received this message because you are subscribed to the Google Groups
> "Hippo Community" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to hippo-communi...@googlegroups.com.
> Visit this group at http://groups.google.com/group/hippo-community.
> For more options, visit https://groups.google.com/d/optout.



--
Amsterdam - Oosteinde 11, 1017 WT Amsterdam
Boston - 745 Atlantic Ave, 8th Floor, MA 02111

US +1 877 414 4776
Europe +31(0)20 522 4466
www.onehippo.com

Gangel Dávid

unread,
Jul 30, 2015, 12:23:45 AM7/30/15
to Hippo Community, n.vanka...@onehippo.com
Hi,

Okay as I see now a bit more clearly the issue let me summarize it.
So I have an Angular2 app which gets it's views from the CMS generated by the HST using freemarker templates.
Angular app(skins.ts):

/// <reference path="../../custom_typings/_custom.d.ts" />

import { Component, View } from 'angular2/annotations';
import { routerDirectives, RouteConfig } from 'angular2/router';
import { Home } from '../home/home';
import { Prices } from '../prices/prices';

@Component({
selector: 'skins',
properties: ['templateurl: string']
})

@View({
directives: [routerDirectives],
templateUrl: "/components/app/skins.html"
})

@RouteConfig([
{ path: '/', component: Home, as: 'home' },
{ path: '/arak', component: Prices, as: 'prices'}
])

// Component controller
export class Skins {
}

base-layout.ftl(copying only the body section):
       <body class="header-fixed header-fixed-space">
<div class="wrapper">
<skins>
</skins>
</div>
<#if hstRequest.requestContext.cmsRequest>
<#assign app>
  <@hst.webfile path="/js/dist/bootstrap_cms.js"/>
</#assign>
<script>
System.import('${app?keep_after("/site/")?keep_before(".js")}');
</script>
<#else>
<#assign app>
  <@hst.webfile path="/js/dist/bootstrap.js"/>
</#assign>
<script>
System.import('${app?keep_after("/")?keep_before(".js")}');
</script>
</#if>
</body>

I hope this is enough for now.
My symptoms:
1. The site in the browser looks as expected.
2. Opening the channel in the chanel manager looks the same.
3. Pressing on the Edit button to edit the channel reloads the page with expected look but does not renders the edit menu button.

I think the issue is that there is no <@hst.include> for the relevant part inside the base-layout.ftl. Of course there is no include. Angular renders it. And I think because of this the HST does not knows that the request made by through the CMS.

Am I right with my assumption?

Gangel Dávid

unread,
Jul 30, 2015, 6:31:23 AM7/30/15
to Hippo Community, n.vanka...@onehippo.com, gan...@gmail.com
Or maybe I should turn on async property for the component and use as ESI?

Gangel Dávid

unread,
Jul 30, 2015, 9:19:59 AM7/30/15
to Hippo Community, n.vanka...@onehippo.com, gan...@gmail.com
I have made a bit research for today and also made a chat with PatrickJS from the Angular project about the issue.
Relevant ticket can be found here:
It also includes a video.

So basically as I see the perfect solution would be to give the possibility to the Hippo developer to define which component should be rendered at server side with which technique. Basically this is already implemented in hippo by giving the property of hst:async.
Now the problem is that probably the most suitable supported method would be ESI, but as I see it's a kind of left alone standard. Still not W3C specification since almost 15years and just small amount of CDN providers are supporting it.

But another solution would be to render the website with nodejs on the server.

PatrickJS has a new project which should bring serverside rendering to the Angular:

Documentation:
https://docs.google.com/document/d/1q6g9UlmEZDXgrkY88AJZ6MUrUxcnwhBGS0EXbVlYicY/edit#

And there are also other JS based frameworks that does support it like in this article:

Summarizing the whole stuff my feature request would be to run a nodejs app inside the java jvm which can pre-render the site based on the configuration and send it over to the clients.

I won't list all the benefits having this feature. The linked documentation shows them.

Would be nice if hippo core developers could take a look and discuss the thoughts about this.

Thank you.

Niels van Kampenhout

unread,
Jul 30, 2015, 10:04:15 AM7/30/15
to Hippo Community
I think your assumption makes sense, but as I have no experience with
Angular in the Channel Manager I can't say for sure. I'm not sure we
support Angular in the Channel Manager officially.

Perhaps you can use a workaround, like an extra (server side) HST
component that (in case of CMS request only) gets the menu object and
renders the menu edit button. In the site the component would do
nothing.

Maybe others with more Angular experience can comment.

Regards,
Niels

Minos Chatzidakis

unread,
Jul 30, 2015, 12:06:15 PM7/30/15
to hippo-c...@googlegroups.com, Niels van Kampenhout, gan...@gmail.com
Hi Gangel,

I have no experience with Angular 2 but I think the following comments are still valid:

On Thu, Jul 30, 2015 at 3:19 PM, Gangel Dávid <gan...@gmail.com> wrote:
I have made a bit research for today and also made a chat with PatrickJS from the Angular project about the issue.
Relevant ticket can be found here:
It also includes a video.

So basically as I see the perfect solution would be to give the possibility to the Hippo developer to define which component should be rendered at server side with which technique. Basically this is already implemented in hippo by giving the property of hst:async.

True but I don't think you need the hst:async property. Using hst:async means that when HST renders your site, instead of calling the async component it adds a javascript snippet that will call it after the page has loaded. But you're rendering with Angular which also begins processing after the page has loaded (onload). So this complicates thing a lot when using async. I think you just need the hst:standalone property (which is by default true btw).

 
Now the problem is that probably the most suitable supported method would be ESI, but as I see it's a kind of left alone standard. Still not W3C specification since almost 15years and just small amount of CDN providers are supporting it.

But another solution would be to render the website with nodejs on the server.

PatrickJS has a new project which should bring serverside rendering to the Angular:

Documentation:
https://docs.google.com/document/d/1q6g9UlmEZDXgrkY88AJZ6MUrUxcnwhBGS0EXbVlYicY/edit#

And there are also other JS based frameworks that does support it like in this article:

Out of curiosity, are you using Angular to build a website or a web application?

 

Summarizing the whole stuff my feature request would be to run a nodejs app inside the java jvm which can pre-render the site based on the configuration and send it over to the clients.

Why a nodejs app and not HST?
 

I won't list all the benefits having this feature. The linked documentation shows them.

The linked documentation, especially the video found in your last link (https://www.youtube.com/watch?v=0wvZ7gakqV4), shows that using client side Angular for websites has limitations, mainly these being misbehaving URLs and crippled SEO support from Google. URLs are problematic in Angular since they are not really locators to a resource but to a javascript app that needs to run in a browser in order to load that resource (and in an async way). So yes, moving to server side has benefits.


Now to focus on why the cmseditmenu won't work, it won't cause it runs client side after the page has loaded. You can see this in org.hippoecm.hst.tag.HstCmsEditMenuTag#write where an HTML comment is written out to the page. If you're using the hst tag in your FTLs you should be seeing these comments. When the page has loaded in Channel manager, a javascript reads these comments and creates the buttons. 

This javascript is injected in the HTML page once you press Edit in Channel manager, and it is set to run onload. But that's also true for Angular, so you are getting in a race condition. If the CM javascript runs first, then there's no HTML yet to process, Angular hasn't loaded it yet.  

Ideally the CM javascript should run after Angular has finished loading, so all the HTML and those crucial comments are there. But Angular provides no event to notify it has finished processing, so there's nothing to hook to. Huge, but also reasonable, limitation from Angular.

By the way I saw your FTL but I didn't see the cmseditmenu tag in there. 
Last, I think you don't need to use hst:include since you (seem to) want to load each hst component separately, and aggregate their outputs in Angular.

hth
Minos
--
Amsterdam - Oosteinde 11, 1017 WT Amsterdam
Boston - 745 Atlantic Ave, Eight Floor, MA 02111

US +1 877 414 4776 (toll free)

Gangel Dávid

unread,
Jul 31, 2015, 2:33:47 AM7/31/15
to Hippo Community, n.vanka...@onehippo.com, gan...@gmail.com, m.chat...@onehippo.com
Hi,

Out of curiosity, are you using Angular to build a website or a web application?
Firstly website which later becomes features so becoming a webapp. But I think it doesn't really meter. In the near future more and more websites will popup which are webapps in today's terminology.


Why a nodejs app and not HST?
Hm, okay didn't think about that, if it would be able to run angular or whatever framework inside.

I was able to solve in a bit hacky way my problem with:

          <body class="header-fixed header-fixed-space">
<#assign app>
  <@hst.webfile path="/js/dist/bootstrap.js"/>
</#assign>
<#if hstRequest.requestContext.cmsRequest>
<skins>
<@hst.include ref="skins-bootstrap"/>
</skins>
<script>
System.import('${app?keep_after("/site/")?keep_before(".js")}');
</script>
<#else>
<skins>
</skins>
<script>
System.import('${app?keep_after("/")?keep_before(".js")}');
</script>
</#if>
</body>

In this case the site renders fine in normal browser, and when editing the channel the edit menu button is also displayed.

Should I raise a more generic ticket in Hippo's jira like:
Add support for HST to be able to render server side HTMLs which also uses JS frameworks like Angular,Backbone,Ember etc...

Minos Chatzidakis

unread,
Jul 31, 2015, 5:03:08 AM7/31/15
to Gangel Dávid, Hippo Community, Niels van Kampenhout
On Fri, Jul 31, 2015 at 8:33 AM, Gangel Dávid <gan...@gmail.com> wrote:
Hi,


Glad you have it working! Seeing your ftl I can't see how your solution works unfortunately.

 

Should I raise a more generic ticket in Hippo's jira like:
Add support for HST to be able to render server side HTMLs which also uses JS frameworks like Angular,Backbone,Ember etc...

It's not really clear to me what level of integration you're talking about. Both HST and js frameworks are quite complex and large. There are tens of usage scenarios and possible integrations, so you may need to explain in detail what you mean with "HTMLs which also uses JS frameworks".



Minos
--

Gangel Dávid

unread,
Aug 3, 2015, 5:36:05 AM8/3/15
to Hippo Community, gan...@gmail.com, n.vanka...@onehippo.com
Hi,

Actually it turned out it hasn't solved the issue.
But finally I have it working.
Important thing in Angular2 is the "." char for the path of the template. The base href defines under which path the app is running. This I haven't set before unfortunately as I just realized that the cms preview has a subpath.
And the edit button is not showing was caused by this wrong url setup. The menu was requested by an url which didn't contained the _cmsinternal part.
Now with this setup it does and everything works fine:

In the header:

                <#if hstRequest.requestContext.cmsRequest>
<#assign escape_string="/site/">
<#assign base_href="/site/_cmsinternal/">
<#else>
<#assign escape_string="/">
  <#assign base_href="/">
</#if>
<base href=${base_href}>

         <body class="header-fixed header-fixed-space">
<skins>
</skins>
<#assign app>
<@hst.webfile path="/js/dist/bootstrap.js"/>
</#assign>
<script>
System.import('${app?keep_after(escape_string)?keep_before(".js")}');
</script>
</body>
Reply all
Reply to author
Forward
0 new messages