# HG changeset patch
# User Katia Saurfelt <katia.saurfelt@logilab.fr>
# Date 1394618165 -3600
#      Wed Mar 12 10:56:05 2014 +0100
# Node ID 50d7d3b4a41e37c059cdfbb8710aee83898af12c
# Parent  9d85cd2fb37b102068df68ef57b0ad88bede2f51
[header] make `main_header` more bootstrap compilant (related to #3597030)

diff --git a/doc/html_page_header.rst b/doc/html_page_header.rst
new file mode 100644
--- /dev/null
+++ b/doc/html_page_header.rst
@@ -0,0 +1,28 @@
+class HTMLPageHeader
+====================
+
+This class has been completly rewritten.
+
+* new context `header-logo` has been introducted for logo and site
+  title (used by `basecomponents.ApplLogo` and
+  `basecomponents.ApplicationName`) to be displyed on the very left of
+  the navbar.
+
+* Breadcumbs habe been removed from the header to a specific div.
+
+* A new dict `headers_classes` now provids the match between context
+  and bootsrap classes ::
+
+  basetemplates.HTMLPageHeader.headers_classes = {
+     'header-left':'navbar-left',
+     'header-right':'navbar-right',
+    }
+
+
+* A new dict `css` provides the possiliblity to easily customize the
+  header navbar and breadcrumbs ::
+
+  basetemplates.HTMLPageHeader.css = {
+     'header-navbar' : 'navbar-default',
+     'breadcrumbs'   : 'cw-breadcrumbs-default'
+  }
diff --git a/views/__init__.py b/views/__init__.py
--- a/views/__init__.py
+++ b/views/__init__.py
@@ -16,3 +16,16 @@
 # with this program. If not, see <http://www.gnu.org/licenses/>.
 
 """cubicweb-squareui views/forms/actions/components for web ui"""
+from cubicweb.web.views.boxes import ContextualBoxLayout, contextual
+
+_ = unicode
+
+class SimpleBoxContextFreeBoxLayout(ContextualBoxLayout):
+    __select__ = ~contextual()
+    cssclass = 'contextFreeBox'
+    __regid__ = 'simple-layout'
+
+    def render(self, w):
+        if self.init_rendering():
+            view = self.cw_extra_kwargs['view']
+            view.render_body(w)
diff --git a/views/basetemplates.py b/views/basetemplates.py
--- a/views/basetemplates.py
+++ b/views/basetemplates.py
@@ -12,8 +12,11 @@
 from logilab.mtconverter import xml_escape
 
 from cubicweb.utils import UStringIO
-from cubicweb.web.views import basetemplates
 
+from cubicweb.web.views import basetemplates, \
+     basecomponents
+
+from cubicweb.web.views.boxes import SearchBox
 
 HTML5 = u'<!DOCTYPE html>'
 
@@ -92,12 +95,11 @@
 @monkeypatch(basetemplates.TheMainTemplate)
 def content_column(self, view, content_cols):
     w = self.w
-    w(u'<div id="contentColumn" class="col-md-%s">' % content_cols)
+    w(u'<div id="pageContent" class="col-md-%(col)s" role="main">' % {
+        'col': content_cols})
     components = self._cw.vreg['components']
     self.content_components(view, components)
     self.content_header(view)
-    w(u'<div class="row">')
-    w(u'<div id="pageContent">')
     vtitle = self._cw.form.get('vtitle')
     if vtitle:
         w(u'<div class="vtitle">%s</div>\n' % xml_escape(vtitle))
@@ -110,8 +112,6 @@
     view.render(w=w)
     w(u'</div>\n') # closes id=contentmain
     w(nav_html.getvalue())
-    w(u'</div>\n' # closes id=pageContent
-      u'</div>\n') # closes row
     self.content_footer(view)
     w(u'</div>\n') # closes div#contentColumn in template_body_header
 
@@ -148,26 +148,117 @@
     self.w(u'</div>\n') # closes id="page"
     self.w(u'</body>\n')
 
+
+# main header
+
+basecomponents.ApplLogo.context = 'header-logo'
+# use basecomponents.ApplicationName.visible = False
+basecomponents.ApplicationName.context = 'header-logo'
+basecomponents.ApplLogo.order = 1
+basecomponents.ApplicationName.order = 10
+basecomponents.CookieLoginComponent.order = 10
+basecomponents.AuthenticatedUserStatus.order = 5
+SearchBox.order = 0
+SearchBox.context = 'header-right'
+SearchBox.layout_id = 'simple-layout'
+
+basetemplates.HTMLPageHeader.headers_classes = {
+     'header-left':'navbar-left',
+     'header-right':'navbar-right',
+    }
+
+@monkeypatch(basetemplates.HTMLPageHeader)
+def call(self, view, **kwargs):
+    self.main_header(view)
+    self.breadcrumbs(view)
+    self.state_header()
+
+def get_components(self, view, context):
+    ctxcomponents = self._cw.vreg['ctxcomponents']
+    return ctxcomponents.poss_visible_objects(self._cw,
+                                              rset=self.cw_rset,
+                                              view=view,
+                                              context=context)
+
+basetemplates.HTMLPageHeader.get_components = get_components
+basetemplates.HTMLPageHeader.css = {'header-navbar' : 'navbar-default',
+                                    'breadcrumbs'   : 'cw-breadcrumbs-default'}
+
 @monkeypatch(basetemplates.HTMLPageHeader)
 def main_header(self, view):
-    """build the top menu with authentification info and the rql box"""
-    spans = {'headtext': 'col-md-2',
-             'header-center': 'col-md-9',
-             'header-right': 'col-md-1 pull-right',
-             }
     w = self.w
-    w(u'<div id="header" class="navbar navbar-default" role="navigation">'
-      u'<div class="container">')
-    for colid, context in self.headers:
-        w(u'<div id="%s" class="%s">' % (colid, spans.get(colid, 'col-md-2')))
-        components = self._cw.vreg['ctxcomponents'].poss_visible_objects(
-            self._cw, rset=self.cw_rset, view=view, context=context)
-        for comp in components:
-            comp.render(w=w)
-            w(u'&#160;')
-        w(u'</div>\n')
-    w(u'</div>\n') # closes class="container,
-    w(u'</div>\n') # closes id="header"
+    title = self._cw.property_value('ui.site-title')
+    w(u'<header class="navbar %s" role="banner">' %
+      self.css.get('header-navbar', 'header-navbar'))
+    w(u'<nav class="container-fluid">')
+    self.dispaly_navbar_header(w, view)
+    self.display_header_components(w, view, 'header-left')
+    self.display_header_components(w, view, 'header-right')
+    w(u'</nav></header>')
+
+def dispaly_navbar_header(self, w, view):
+    w(u'''<div class="navbar-header">
+    <button class="navbar-toggle" data-target="#tools-group" data-toggle="collapse" type="button">
+    <span class="sr-only">%(toggle_label)s</span>
+    <span class="icon-bar"></span>
+    <span class="icon-bar"></span>
+    <span class="icon-bar"></span>
+    </button>''' % {'toggle_label':self._cw._('Toggle navigation')})
+    components = self.get_components(view, context='header-logo')
+    if components:
+        for component in components:
+            component.render(w=w)
+    w(u'</div>')
+
+basetemplates.HTMLPageHeader.dispaly_navbar_header = dispaly_navbar_header
+
+def display_header_components(self, w, view, context):
+    components = self.get_components(view, context=context)
+    if components:
+        w(u'<div id="tools-group" class="collapse navbar-collapse">')
+        w(u'<ul class="nav navbar-nav %s">' % \
+          self.headers_classes[context])
+        for component in components:
+            w(u'<li>')
+            component.render(w=w)
+            w(u'</li>')
+        w(u'</ul>')
+        w(u'</div>')
+
+basetemplates.HTMLPageHeader.display_header_components = display_header_components
+
+@monkeypatch(basetemplates.HTMLPageHeader)
+def breadcrumbs(self, view):
+    components = self.get_components(view, context='header-center')
+    if components:
+        self.w(u'<nav role="navigation" class="%s">' %
+            self.css.get('breadcrumbs', 'breadcrumbs-defaul'))
+        self.w(u'<div class="container">')
+        for component in components:
+            component.render(w=self.w)
+        self.w(u'</div>')
+        self.w(u'</nav>')
+
+@monkeypatch(basetemplates.HTMLPageHeader)
+def state_header(self):
+    state = self._cw.search_state
+    if state[0] == 'normal':
+        return
+    _ = self._cw._
+    value = self._cw.view('oneline', self._cw.eid_rset(state[1][1]))
+    target, eid, r_type, searched_type = self._cw.search_state[1]
+    cancel_link = u'<a href="%(url)s" role="button" title="%(title)s">[%(title)s]</a>' % {
+        'url' : self._cw.build_url(str(eid),
+                                   vid='edition', __mode='normal'),
+        'title': _('cancel')}
+    msg = ' '.join((_("searching for"),
+                    display_name(self._cw, state[1][3]),
+                    _("to associate with"), value,
+                    _("by relation"),
+                    '<strong>"%s"</strong>' % \
+                    display_name(self._cw, state[1][2], state[1][0]),
+                    cancel_link))
+    return self.w(u'<div class="alert alert-info">%s</div>' % msg)
 
 @monkeypatch(basetemplates.HTMLPageFooter)
 def call(self, **kwargs):
@@ -176,3 +267,7 @@
     self.footer_content()
     self.w(u'</div>\n')
     self.w(u'</footer>\n')
+
+def registration_callback(vreg):
+    vreg.register_all(globals().values(), __name__)
+    vreg.unregister(actions.CancelSelectAction)