Problems with the MENU helper function and HTML5

555 views
Skip to first unread message

Sverre

unread,
Dec 29, 2012, 10:11:29 AM12/29/12
to web...@googlegroups.com
I'm trying to write a layout plugin with the styles of http://metroui.org.ua . A problem is, that he is using custom data in the menu definitions like 
 
  • <ul class="menu">
  • <li data-role="dropdown">
  • <a href="#">Item 1</a>
  • <ul class="dropdown-menu">
  • <li><a href="#">SubItem</a></li>
  • ...
  • <li><a href="#">SubItem</a></li>
  •  

So either I have to extend the MENU function or I have to find a another solution. Has someone a hint?

Thx in advance



 

Paolo Caruccio

unread,
Dec 29, 2012, 11:06:18 AM12/29/12
to web...@googlegroups.com
One possible solution (not tested).

1 step) in static/js create a new file named "web2py_metroui.js" having the following contents

jQuery(function(){
  jQuery
('.menu>li.dropdown').each(function(){
      jQuery
(this).attr({'class':'','data-role':'dropdown'});
 
});
  jQuery
('.menu li li').each(function(){
   
if(jQuery(this).find('ul').length)
      jQuery
(this).addClass('dropdown-submenu');
 
});
});

2 step) in layout.html 
a) replace existing line with (note the voice "menu")
{{=MENU(response.menu, _class='mobile-menu nav' if is_mobile else 'nav menu', mobile=is_mobile,  li_class='dropdown',  ul_class='dropdown-menu')}}

b) replace this line
<script src="{{=URL('static','js/web2py_bootstrap.js')}}"></script>
with
<script src="{{=URL('static','js/web2py_metroui.js')}}"></script>

c) remove all other refererences to bootstrap.

Sverre

unread,
Dec 29, 2012, 5:50:35 PM12/29/12
to web...@googlegroups.com
Thx for your hint. I'm not knowing js at all, but I found a solution:

$(document).ready(function(){
   jQuery('div.nav-bar ul').each(function(){
     jQuery(this).removeClass('web2py-menu web2py-menu-vertical');
     jQuery(this).addClass('menu');        
   });
   jQuery('li.web2py-menu-first').each(function(){
     jQuery(this).removeClass('web2py-menu-expand web2py-menu-first web2py-menu-last web2py-menu-active');
   });
   jQuery('li.web2py-menu-expand').each(function(){
     jQuery(this).attr({'data-role':'dropdown'});
     jQuery(this).removeClass('web2py-menu-expand web2py-menu-first web2py-menu-last web2py-menu-active');
   });
   jQuery('ul.menu li ul').each(function(){
     jQuery(this).removeClass('menu');
     jQuery(this).addClass('dropdown-menu');        
   });
});


This solves my problem, but isn't really elegant. It's time to write a new MENU helper function. 

Paolo Caruccio

unread,
Dec 30, 2012, 5:01:28 PM12/30/12
to web...@googlegroups.com
I don't think that MENU helper is the guilty in your case.
I made a metroui version of welcome app (see the images).
Follows the list of involved files:

1) views/layout.html
This is the main file to change if someone want apply a different html/css theme to web2py apps
Each css framework has its own layout scaffold so we have to adapt our html structure.
For example bootstrap menu html structure is (but the same is valid for other parts of the layout. For details please check the file in attached app):

   <!-- Navbar ================================================== -->
 
<div class="navbar navbar-inverse navbar-fixed-top">
   
<div class="flash">{{=response.flash or ''}}</div>
   
<div class="navbar-inner">
     
<div class="container">
       
<!-- the next tag is necessary for bootstrap menus, do not remove -->
       
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
         
<span class="icon-bar"></span>
         
<span class="icon-bar"></span>
         
<span class="icon-bar"></span>
       
</button>
        {{=response.logo or ''}}
       
<ul id="navbar" class="nav pull-right">{{='auth' in globals() and auth.navbar(mode="dropdown") or ''}}</ul>
       
<div class="nav-collapse">
          {{is_mobile=request.user_agent().is_mobile}}
          {{if response.menu:}}
          {{=MENU(response.menu, _class='mobile-menu nav' if is_mobile else 'nav',mobile=is_mobile,li_class='dropdown',ul_class='dropdown-menu')}}
          {{pass}}
       
</div><!--/.nav-collapse -->
     
</div>
   
</div>
 
</div><!--/top navbar -->


with metroui the menu becomes:

<div class="page">
   
<!-- Navbar ================================================== -->
   
<div class="nav-bar">
       
<div class="nav-bar-inner padding10">
           
<span class="pull-menu"></span>
           
<!--{{=response.logo or ''}}-->
           
<a href="http://www.web2py.com/"><span class="element brand"><b>web<span>2</span>py</b>&trade;&nbsp;</span></a>




           
<div class="divider"></div>
           
            {{is_mobile=request.user_agent().is_mobile}}
            {{if response.menu:}}
                {{=MENU(response.menu, _class='menu', mobile=False, li_class='dropdown', ul_class='dropdown-menu')}}
            {{pass}}




       
</div>
   
</div>
</div>

Another important change is related to files (css, javascript) that the theme will use. So:

  <!-- include stylesheets -->
  {{  
  response.files.append(URL('static','css/web2py.css'))
  response.files.append(URL('static','css/bootstrap.min.css'))
  response.files.append(URL('static','css/bootstrap-responsive.min.css'))
  response.files.append(URL('static','css/web2py_bootstrap.css'))
  }}
 ...
 
<noscript><link href="{{=URL('static', 'css/web2py_bootstrap_nojs.css')}}" rel="stylesheet" type="text/css" /></noscript>
...
 
<!-- The javascript =============================================
       (Placed at the end of the document so the pages load faster) -->

 
<script src="{{=URL('static','js/bootstrap.min.js')}}"></script>

 
<script src="{{=URL('static','js/web2py_bootstrap.js')}}"></script>


becomes (please note that I put metroui files in a separated folder for clarity):

  <!-- include stylesheets -->
  {{  
  response.files.append(URL('static','css/web2py.css'))
  response.files.append(URL('static','metroui/css/modern.css'))
  response.files.append(URL('static','metroui/css/modern-responsive.css'))
  response.files.append(URL('static','metroui/css/web2py_metroui.css'))
  }}
...
<noscript><link href="{{=URL('static', 'metroui/css/web2py_metroui_nojs.css')}}" rel="stylesheet" type="text/css" /></noscript>


...
 
<!-- The javascript =============================================
       (Placed at the end of the document so the pages load faster) -->

 
<script src="{{=URL('static','metroui/js/web2py_metroui.js')}}"></script>
 
<script src="{{=URL('static','metroui/js/dropdown.js')}}"></script>

2) static/metroui/web2py_metroui.css
This file is needed to insert your customization or to override the rules in web2py.css and in original files of framework.

3)static/metroui/css/web2py_metroui_nojs.css
As #2 but applied when javascript is disabled in the browser. It's empty for metroui.

4) static/metroui/js/web2py_metroui.js
In this file we will write mainly the code to add, remove, replace the html tags attributes (classes, data-* and so on) generated automatically by web2py in order to comply with selected framework requirements
For example, since metroui requires the data-role attributes for the li.dropdown and the menu is generated with the MENU helper we need to write the following code:

jQuery(function(){
  jQuery
('.menu>li.dropdown').each(function(){

      jQuery
(this).attr({'data-role':'dropdown'});
 
});
});


5) views/default/index.html
{{=A(T("Administrative Interface"), _href=URL('admin','default','index'), _class='btn',

becomes

{{=A(T("Administrative Interface"), _href=URL('admin','default','index'), _class='button',

6) models/menu.py
we need to remove the href from link, otherwise the click event to open the dropdown menu doesn't fire
    response.menu += [
       
#(SPAN('web2py', _class='highlighted'), False, 'http://web2py.com', [
       
(SPAN('web2py', _class='highlighted'), False, '#', [


Final notes:
1) Classes you removed (web2py-menu-expand web2py-menu-first web2py-menu-last web2py-menu-active) don't influence the metroui menu
2) metroui framework doesn't support nested submenu if I'm not missing something
3) dropdown.js (metroui file) has a small bug on line 91:
$('.menul-pull')
instead of
$('.pull-menu')

4) attached w2p app is only demonstrative so my apologies in advance for eventual bugs you'll find
metroui_welcome_galaxySIII_2.png
metroui_welcome_galaxySIII_1.png
metroui_welcome_ipad2.png
metroui_welcome_ipad1.png
metroui_welcome_iphone2.png
metroui_welcome_iphone1.png
metroui_welcome_layout.png
web2py.app.metroui.zip

Paolo Caruccio

unread,
Dec 31, 2012, 1:24:37 PM12/31/12
to web...@googlegroups.com
I noted that my previous post is uncomplete. In the following the missing part:
 
Happy New Year!!
<!-- The javascript =============================================
    &nbs...
Mostra originale

Sverre

unread,
Dec 31, 2012, 9:05:19 PM12/31/12
to web...@googlegroups.com
Thank you very much for your answer in detail, especially the hint for  the bug. I found more bugs too with the firefox webconsole. But because this is work in progress, I'm able to live with that.

A happy new year!

Sverre






           
<span style="color:#00...
Vis original
Reply all
Reply to author
Forward
0 new messages