def render(self, posts_per_page=25): pages_count = (len(self.rendered_items) + posts_per_page - 1) // posts_per_page page_names = ["%d.html" % i for i in range(pages_count)] nav_section = T.nav( *[T.a(str(i), href=page_names[i], target=_PAGE_FRAME) for i in range(pages_count)] ) index = T.html( T.head( T.meta(charset='utf-8'), stylesheet(_STYLE_CSS), stylesheet(_NAVBAR_CSS), T.script(src=_JQUERY_URL), inline_script_from(get_resource(Path(_SELECTED_JS))) ), T.body( nav_section, T.iframe(name=_PAGE_FRAME, src=page_names[0] if pages_count > 0 else 'none', width='100%', height='100%', style='border:none') ) ) self.pages['index.html'] = index for page_index in range(pages_count): page_items = self.rendered_items[page_index * posts_per_page: (page_index + 1) * posts_per_page] chunk_html = T.html( T.head(stylesheet('page.css')), T.body( T.div(*page_items, id=ID_CONTAINER) ) ) self.pages[page_names[page_index]] = chunk_html
def visit_Navbar(self, node): node_id = self.id or sha1(str(id(node)).encode()).hexdigest() root = tags.nav() if self.html5 else tags.div(role='navigation') root['class'] = 'navbar navbar-inverse navbar-fixed-top' cont = root.add(tags.div(_class='container')) # collapse button header = cont.add(tags.div(_class='navbar-header')) btn = header.add(tags.button(**{'type': 'button', 'class': 'navbar-toggle collapsed', 'data-toggle': 'collapse', 'data-target': '#' + node_id, 'aria-expanded': 'false', 'aria-controls': 'navbar'})) btn.add(tags.span('Toggle navigation', _class='sr-only')) btn.add(tags.span(_class='icon-bar')) btn.add(tags.span(_class='icon-bar')) btn.add(tags.span(_class='icon-bar')) # title may also have a 'get_url()' method, in which case we render # a brand-link if node.title is not None: if hasattr(node.title, 'get_url'): header.add(tags.a(node.title.text, _class='navbar-brand', href=node.title.get_url())) else: header.add(tags.span(node.title, _class='navbar-brand')) bar = cont.add(tags.div(_class='navbar-collapse collapse', id=node_id)) for item in node.items: bar.add(self.visit(item)) return root
def __get__(self, obj: Table, objtype: Any = None) -> html_tag: total = span(obj.total_rows, data_table_target="total") desc = div(total, span(" results"), _class="text-gray-500") button_class = ( "relative inline-flex items-center px-2 py-1 border border-gray-200" " bg-white text-gray-500 hover:bg-gray-50 focus:outline-none" ) first_button = button( IconFirstPage().to_tag(), data_action="click->table#firstPage", _class=button_class + " rounded-l", ) prev_button = button( IconPreviousPage().to_tag(), data_action="click->table#previousPage", _class=button_class, ) next_button = button( IconNextPage().to_tag(), data_action="click->table#nextPage", _class=button_class, ) last_button = button( IconLastPage().to_tag(), data_action="click->table#lastPage", _class=button_class + " rounded-r", ) class_ = "relative z-0 inline-flex shadow-sm -space-x-px" buttons = nav(first_button, prev_button, next_button, last_button, _class=class_) class_ = "flex justify-between items-center px-2 py-2" div_ = div(desc, buttons, _class=class_) return div_
def visit_Navbar(self, node): # create a navbar id that is somewhat fixed, but do not leak any # information about memory contents to the outside # node_id = self.id or sha1(str(id(node)).encode()).hexdigest() root = tags.div() root['class'] = "navbar-dark text-white" container = root.add(tags.div()) container['class'] = "container" root = tags.nav() if self.html5 else tags.div(role='navigation') root['class'] = 'navbar px-0 navbar-expand-lg navbar-dark' # collapse button # header = nav.add(tags.div(_class='navbar-header')) # btn = header.add(tags.button()) btn = root.add(tags.button()) btn['type'] = 'button' btn['class'] = 'navbar-toggler' btn['data-toggle'] = 'collapse' btn['data-target'] = '#navbarNavAltMarkup' btn['aria-expanded'] = 'false' btn['aria-controls'] = 'navbarNavAltMarkup' btn['aria-label'] = 'Toggle navigation' btn.add(tags.span(_class='navbar-toggler-icon')) bar = root.add(tags.div(id='navbarNavAltMarkup', _class='navbar-collapse collapse')) bar_list = bar.add(tags.div(_class='navbar-nav')) for item in node.items: bar_list.add(self.visit_Link(item)) return root
def visit_Navbar(self, node): cont = tags.nav( _class='navbar fixed-top navbar-expand-sm navbar-dark bg-secondary' ) if current_user.is_authenticated: # navbar is empty if not logged in, therefore no toggle button needed btn_toggle_kwargs = { 'class': 'navbar-toggler', 'type': 'button', 'data-toggle': 'collapse', 'data-target': '#navbarCollapseDiv', 'aria-controls': 'navbarCollapseDiv', 'aria-expanded': 'false', 'aria-label': 'Toggle navigation' } btn_toggle = cont.add(tags.button(**btn_toggle_kwargs)) btn_toggle.add(tags.span(_class='navbar-toggler-icon')) else: cont[ 'class'] += ' display-flex justify-content-end' # so that the sign in button is always on the right div_coll = cont.add( tags.div(_class='collapse navbar-collapse', id='navbarCollapseDiv')) div_nav = div_coll.add(tags.div(_class='navbar-nav')) for item in node.items: div_nav.add(self.visit(item)) cont.add(create_login_logout_btn(current_user.is_authenticated)) return cont
def visit_Navbar(self, node): # create a navbar id that is somewhat fixed, but do not leak any # information about memory contents to the outside node_id = self.id or sha1(str(id(node)).encode()).hexdigest() root = tags.nav() if self.html5 else tags.div( role='navigation') root['class'] = 'navbar navbar-default' cont = root.add(tags.div(_class='container-fluid')) # collapse button header = cont.add(tags.div(_class='navbar-header')) btn = header.add(tags.button()) btn['type'] = 'button' btn['class'] = 'navbar-toggle collapsed' btn['data-toggle'] = 'collapse' btn['data-target'] = '#' + node_id btn['aria-expanded'] = 'false' btn['aria-controls'] = 'navbar' btn.add(tags.span('Toggle navigation', _class='sr-only')) btn.add(tags.span(_class='icon-bar')) btn.add(tags.span(_class='icon-bar')) btn.add(tags.span(_class='icon-bar')) # title may also have a 'get_url()' method, in which case we render # a brand-link if node.title is not None: if hasattr(node.title, 'get_url'): header.add( tags.a(node.title.text, _class='navbar-brand', href=node.title.get_url())) else: header.add(tags.span(node.title, _class='navbar-brand')) bar = cont.add( tags.div( _class='navbar-collapse collapse', id=node_id, )) bar_list = bar.add(tags.ul(_class='nav navbar-nav')) bar_list_right = bar.add( tags.ul(_class='nav navbar-nav navbar-right')) to_right = False for item in node.items: if isinstance(item, SeparatorAlign): to_right = True continue if not to_right: bar_list.add(self.visit(item)) else: bar_list_right.add(self.visit(item)) return root
def to_tag(self): uls = (self._ul_left, self._ul_center, self._ul_right) nav_ = nav( *uls, _class="p-4 flex justify-between bg-dark h-full border-cgrey_200") tag = div(nav_, _class="flex-1 flex flex-col overflow-hidden", _style="height: 5vh") return tag
def visit_Navbar(self, node): # create a navbar id that is somewhat fixed, but do not leak any # information about memory contents to the outside node_id = self.id or sha1(str(id(node)).encode()).hexdigest() root = tags.nav() if self.html5 else tags.div(role='navigation') root_class = 'navbar navbar-inverse' if node.navbar_inverse else 'navbar navbar-default' if node.navbar_fixed == 'top': root_class += ' navbar-fixed-top' elif node.navbar_fixed == 'bottom': root_class += ' navbar-fixed-bottom' root['class'] = root_class cont = root.add(tags.div(_class='container-fluid')) # collapse button header = cont.add(tags.div(_class='navbar-header')) btn = header.add(tags.button()) btn['type'] = 'button' btn['class'] = 'navbar-toggle collapsed' btn['data-toggle'] = 'collapse' btn['data-target'] = '#' + node_id btn['aria-expanded'] = 'false' btn['aria-controls'] = 'navbar' btn.add(tags.span('Toggle navigation', _class='sr-only')) btn.add(tags.span(_class='icon-bar')) btn.add(tags.span(_class='icon-bar')) btn.add(tags.span(_class='icon-bar')) # add a custom _class `navbar-logo` to adjust logo image if node.logo_filename is not None: logo_a = tags.a(_class='navbar-left navbar-logo') logo_a.add(tags.img(src=node.get_logo_file_url())) header.add(logo_a) # title may also have a 'get_url()' method, in which case we render # a brand-link if node.title is not None: if hasattr(node.title, 'get_url'): header.add( tags.a(node.title.text, _class='navbar-brand', href=node.title.get_url())) else: header.add(tags.span(node.title, _class='navbar-brand')) bar = cont.add( tags.div( _class='navbar-collapse collapse', id=node_id, )) for item in node.items: bar.add(self.visit(item)) return root
def visit_Navbar(self, node): nav = tags.nav(cls="navbar navbar-expand-lg navbar-dark bg-primary") with nav: tags.span(node.title, cls="navbar-brand") with tags.div(id='navbarColor01', cls="collapse navbar-collapse"): with tags.ul(cls='navbar-nav mr-auto'): for item in node.items: tags.li(self.visit(item)) return nav
def visit_Navbar(self, node): # create a navbar id that is somewhat fixed, but do not leak any # information about memory contents to the outside node_id = self.id or sha1(str(id(node)).encode()).hexdigest() root = tags.nav() if self.html5 else tags.div(role='navigation') root['class'] = 'navbar navbar-default' cont = root.add(tags.div(_class='container-fluid')) # collapse button header = cont.add(tags.div(_class='navbar-header')) btn = header.add(tags.button()) btn['type'] = 'button' btn['class'] = 'navbar-toggle collapsed' btn['data-toggle'] = 'collapse' btn['data-target'] = '#' + node_id btn['aria-expanded'] = 'false' btn['aria-controls'] = 'navbar' btn.add(tags.span('Toggle navigation', _class='sr-only')) btn.add(tags.span(_class='icon-bar')) btn.add(tags.span(_class='icon-bar')) btn.add(tags.span(_class='icon-bar')) # title may also have a 'get_url()' method, in which case we render # a brand-link if node.title is not None: if hasattr(node.title, 'get_url'): # a_tag = tags.a(node.title.text, _class='navbar-brand', # href=node.title.get_url()) style = 'max-width:100px;margin-top: 18px;margin-right: 4px;' header.add( tags.span('pip install', _class='navbar-left hidden-xs', style=style)) a_tag = tags.a(_class='navbar-left', title=node.title.text, href=node.title.get_url()) a_tag.add( tags.img(src='/images/logo_lofi.png', style='max-width:100px;margin-top: 10px;')) header.add(a_tag) else: header.add(tags.span(node.title, _class='navbar-brand')) bar = cont.add( tags.div( _class='navbar-collapse collapse', id=node_id, )) bar_list = bar.add(tags.ul(_class='nav navbar-nav')) for item in node.items: bar_list.add(self.visit(item)) return root
def visit_Navbar(self, node): node_id = self.id or sha1(str(id(node)).encode()).hexdigest() root = tags.nav( _class='navbar navbar-expand-md navbar-dark bg-dark fixed-top') # title may also have a 'get_url()' method, in which case we render # a brand-link if node.title is not None: if hasattr(node.title, 'get_url'): root.add( tags.a(node.title.text, _class='navbar-brand', href=node.title.get_url())) else: root.add(tags.span(node.title, _class='navbar-brand')) btn = root.add(tags.button()) btn['type'] = 'button' btn['class'] = 'navbar-toggler' btn['data-toggle'] = 'collapse' btn['data-target'] = '#' + node_id btn['aria-controls'] = 'navbarCollapse' btn['aria-expanded'] = 'false' btn['aria-label'] = "Toggle navigation" btn.add(tags.span('', _class='navbar-toggler-icon')) bar = root.add( tags.div( _class='navbar-collapse collapse', id=node_id, )) bar_list = bar.add(tags.ul(_class='navbar-nav mr-auto')) for item in node.items: bar_list.add(self.visit(item)) search_form = bar.add(tags.form(_class="form-inline mt-2 mt-md-0")) # search_input = search_form.add(tags.input(_class="form-control mr-sm-2")) # search_input['type'] = "text" # search_input['placeholder'] = "Search" # search_input['aria-label'] = "Search" search_btn = search_form.add( tags.button(_class="btn btn-success my-2 my-sm-0")) search_btn['type'] = "submit" search_btn.add_raw_string('+') search_btn = search_form.add( tags.button(_class="btn btn-success my-2 my-sm-0")) search_btn['type'] = "submit" search_btn.add_raw_string('Login') return root
def visit_Navbar(self, node): kwargs = {'_class': 'navbar'} kwargs.update(self.kwargs) cont = tags.nav(**kwargs) ul = cont.add(tags.ul()) for item in node.items: ul.add(tags.li(self.visit(item))) return cont
def visit_Navbar(self, node): # create a navbar id that is somewhat fixed, but do not leak any # information about memory contents to the outside node_id = self.id or sha1(str(id(node)).encode()).hexdigest() root = tags.nav( _class='navbar navbar-expand-lg navbar-dark bg-dark' ) if self.html5 else tags.div(role='navigation', _class='navbar') if hasattr(node, 'kwargs') and node.kwargs.get('class_'): root['class'] += (' ' + node.kwargs['class_']) if hasattr(node, 'kwargs') and node.kwargs.get('id'): root['id'] = node.kwargs['id'] # title may also have a 'get_url()' method, in which case we render # a brand-link if node.title is not None: if hasattr(node.title, 'img'): root.add(self.visit(node.title)) elif hasattr(node.title, 'get_url'): root.add( tags.a(node.title.text, _class='navbar-brand', href=node.title.get_url())) else: root.add(tags.span(node.title, _class='navbar-brand')) # collapse button if hasattr(node, 'kwargs') and node.kwargs.get('responsive') in (None, True): btn = root.add(tags.button()) btn['type'] = 'button' btn['class'] = 'navbar-toggler navbar-toggler-right' btn['data-toggle'] = 'collapse' btn['data-target'] = '#' + node_id btn['aria-expanded'] = 'false' btn['aria-controls'] = 'navbar' btn['aria-label'] = 'Toggle navigation' btn.add(tags.span(_class='navbar-toggler-icon')) bar = root.add( tags.div( _class='collapse navbar-collapse', id=node_id, )) item_list = bar.add(tags.div(_class='navbar-nav mr-auto')) item_list_right = bar.add(tags.div(_class='navbar-nav')) for item in node.items: if hasattr(item, 'kwargs') and item.kwargs.get('align') == 'right': item_list_right.add(self.visit(item)) else: item_list.add(self.visit(item)) return root
def generateHtml(): with open(path.join(current_dir, '../changelog/', 'storage.json'), 'r') as f: data = json.load(f)[::-1] doc = document(title='Changelog - lkellar.org') articles = [] with doc.head: tags.link(rel='stylesheet', href='style.css') tags.meta(charset="UTF-8") tags.meta(name="description", content="A log of all changes made on lkellar.org") tags.meta(name="viewport", content="width=device-width, initial-scale=1") tags.link(rel="alternate", title="Changelog Feed", type="application/json", href="https://lkellar.org/changelog/feed.json") with doc: with tags.nav().add(tags.ol()): with tags.li(): tags.a("Home", href="../") tags.li("Changelog") with tags.main(): tags.h1('Changelog') for entry in data: tags.hr() article_content = tags.article() with article_content: tags.h2( f'{entry["title"]} - {entry["date"].split("T")[0]}', id=f'{entry["title"]} - {entry["date"]}'.replace( ' ', ''.lower())) list_content = tags.ul() with list_content: for line in entry['items']: line = urls.sub(r'<a href="\2">\1</a>', line) tags.li(raw(line)) articles.append((f'{entry["title"]} - {entry["date"]}'.replace( ' ', ''.lower()), list_content.render(), entry["date"], entry['title'])) with open(path.join(current_dir, '../changelog/', 'index.html'), 'w') as f: f.write(doc.render()) generateFeed(articles)
def visit_Navbar(self, node): kwargs = {'_class': 'navbar'} kwargs.update(self.kwargs) cont = tags.nav(**kwargs) bar = cont.add(tags.div()) for item in node.items: bar.add(self.visit(item)) return cont
def visit_Navbar(self, node): # create a navbar id that is somewhat fixed, but do not leak any # information about memory contents to the outside node_id = self.id or sha1(str(id(node)).encode()).hexdigest() root = tags.nav() if self.html5 else tags.div(role='navigation') root['class'] = 'navbar navbar-default' cont = root.add(tags.div(_class='container-fluid')) # collapse button header = cont.add(tags.div(_class='navbar-header')) btn = header.add(tags.button()) btn['type'] = 'button' btn['class'] = 'navbar-toggle collapsed' btn['data-toggle'] = 'collapse' btn['data-target'] = '#' + node_id btn['aria-expanded'] = 'false' btn['aria-controls'] = 'navbar' btn.add(tags.span('Toggle navigation', _class='sr-only')) btn.add(tags.span(_class='icon-bar')) btn.add(tags.span(_class='icon-bar')) btn.add(tags.span(_class='icon-bar')) # title may also have a 'get_url()' method, in which case we render # a brand-link if node.title is not None: if hasattr(node.title, 'get_url'): header.add(tags.a(node.title.text, _class='navbar-brand', href=node.title.get_url())) else: header.add(tags.span(node.title, _class='navbar-brand')) bar = cont.add(tags.div( _class='navbar-collapse collapse', id=node_id, )) bar_list = bar.add(tags.ul(_class='nav navbar-nav')) bar_list_right = bar.add(tags.ul(_class='nav navbar-nav navbar-right')) to_right = False for item in node.items: if isinstance(item, SeparatorAlign): to_right = True continue if not to_right: bar_list.add(self.visit(item)) else: bar_list_right.add(self.visit(item)) return root
def visit_Navbar(self, node): node_id = self.id or sha1(str(id(node)).encode()).hexdigest() root = tags.nav() if self.html5 else tags.div(role='navigation') if hasattr(node, '_class'): root['class'] = node._class else: root['class'] = 'navbar navbar-default' cont = root.add(tags.div(_class='container-fluid')) # collapse button header = cont.add(tags.div(_class='navbar-header')) btn = header.add(tags.button()) btn['type'] = 'button' btn['class'] = 'navbar-toggle collapsed' btn['data-toggle'] = 'collapse' btn['data-target'] = '#' + node_id btn['aria-expanded'] = 'false' btn['aria-controls'] = 'navbar' btn.add(tags.span('Toggle navigation', _class='sr-only')) btn.add(tags.span(_class='icon-bar')) btn.add(tags.span(_class='icon-bar')) btn.add(tags.span(_class='icon-bar')) if node.title is not None: if hasattr(node.title, 'get_url'): header.add(tags.a(node.title.text, _class='navbar-brand', href=node.title.get_url())) elif hasattr(node.title, 'image'): header.add(tags.span(tags.img(_src=node.title.image, _class='brand-img'), _class='navbar-brand')) else: header.add(tags.span(node.title, _class='navbar-brand')) bar = cont.add(tags.div( _class='navbar-collapse collapse', id=node_id, )) bar_list = bar.add(tags.ul(_class='nav navbar-nav')) bar_list_right = bar.add(tags.ul(_class='nav navbar-nav navbar-right')) for item in node.items: if hasattr(item, 'right'): bar_list_right.add(self.visit(item)) else: bar_list.add(self.visit(item)) return root
def visit_Navbar(self, node): # create a navbar id that is somewhat fixed, but do not leak any # information about memory contents to the outside node_id = self.id or sha1(str(id(node)).encode()).hexdigest() root = tags.nav(_class='navbar') if self.html5 else tags.div(role='navigation', _class='navbar') if node.kwargs.get('class_'): root['class'] += (' ' + node.kwargs['class_']) if node.kwargs.get('id'): root['id'] = node.kwargs['id'] # title may also have a 'get_url()' method, in which case we render # a brand-link if node.title is not None: if hasattr(node.title, 'img'): root.add(self.visit(node.title)) elif hasattr(node.title, 'get_url'): root.add(tags.a(node.title.text, _class='navbar-brand', href=node.title.get_url())) else: root.add(tags.span(node.title, _class='navbar-brand')) # collapse button if node.kwargs.get('responsive') in (None, True): btn = root.add(tags.button()) btn['type'] = 'button' btn['class'] = 'navbar-toggler navbar-toggler-right' btn['data-toggle'] = 'collapse' btn['data-target'] = '#' + node_id btn['aria-expanded'] = 'false' btn['aria-controls'] = 'navbar' btn['aria-label'] = 'Toggle navigation' btn.add(tags.span(_class='navbar-toggler-icon')) bar = root.add(tags.div( _class='collapse navbar-collapse', id=node_id, )) item_list = bar.add(tags.div(_class='navbar-nav mr-auto')) item_list_right = bar.add(tags.div(_class='navbar-nav')) for item in node.items: if item.kwargs.get('align') == 'right': item_list_right.add(self.visit(item)) else: item_list.add(self.visit(item)) return root
def visit_Navbar(self, node): # create a navbar id that is somewhat fixed, but do not leak any # information about memory contents to the outside node_id = self.id or sha1(str(id(node)).encode()).hexdigest() root = tags.nav() if self.html5 else tags.div(role="navigation") root["class"] = "navbar navbar-default" cont = root.add(tags.div(_class="container-fluid")) # collapse button header = cont.add(tags.div(_class="navbar-header")) btn = header.add(tags.button()) btn["type"] = "button" btn["class"] = "navbar-toggle collapsed" btn["data-toggle"] = "collapse" btn["data-target"] = "#" + node_id btn["aria-expanded"] = "false" btn["aria-controls"] = "navbar" btn.add(tags.span("Toggle navigation", _class="sr-only")) btn.add(tags.span(_class="icon-bar")) btn.add(tags.span(_class="icon-bar")) btn.add(tags.span(_class="icon-bar")) # title may also have a 'get_url()' method, in which case we render # a brand-link if node.title is not None: if hasattr(node.title, "get_url"): header.add( tags.a( node.title.text, _class="navbar-brand", href=node.title.get_url(), )) else: header.add(tags.span(node.title, _class="navbar-brand")) bar = cont.add(tags.div(_class="navbar-collapse collapse", id=node_id)) bar_list = bar.add(tags.ul(_class="nav navbar-nav")) for item in node.items: bar_list.add(self.visit(item)) return root
def visit_Navbar(self, node): # create a navbar id that is somewhat fixed, but do not leak any # information about memory contents to the outside node_id = self.id or sha1(str(id(node)).encode()).hexdigest() root = tags.nav() if self.html5 else tags.div(role='navigation') root['class'] = 'navbar navbar-expand-lg navbar-light bg-light' # title may also have a 'get_url()' method, in which case we render # a brand-link if node.title is not None: if hasattr(node.title, 'get_url'): root.add( tags.a(node.title.text, _class='navbar-brand', href=node.title.get_url())) else: root.add(tags.span(node.title, _class='navbar-brand')) # collapse button btn = root.add(tags.button()) btn['type'] = 'button' btn['class'] = 'navbar-toggler navbar-toggler-right' btn['data-toggle'] = 'collapse' btn['data-target'] = '#' + node_id btn['aria-expanded'] = 'false' btn['aria-controls'] = 'navbar' btn['aria-label'] = 'Toggle navigation' btn.add(tags.span(_class='navbar-toggler-icon')) bar = root.add( tags.div( _class='navbar-collapse collapse', id=node_id, )) bar_list = bar.add(tags.div(_class='navbar-nav')) for item in node.items: bar_list.add(self.visit(item)) return root
def visit_Navbar(self, node): # create a navbar id that is somewhat fixed, but do not leak any # information about memory contents to the outside node_id = self.id or sha1(str(id(node)).encode()).hexdigest() root = tags.nav() if self.html5 else tags.div(role='navigation') root['class'] = 'navbar navbar-expand-lg navbar-light bg-light' # cont = root.add(tags.div(_class='container-fluid')) # collapse button # header = cont.add(tags.div(_class='navbar-header')) btn = root.add(tags.button()) btn['class'] = 'navbar-toggler' btn['type'] = 'button' btn['data-toggle'] = 'collapse' btn['data-target'] = '#' + node_id btn['aria-controls'] = node_id btn['aria-expanded'] = 'false' btn['aria-label'] = 'Toggle navigation' # btn.add(tags.span('Toggle navigation', _class='sr-only')) # btn.add(tags.span(_class='icon-bar')) # btn.add(tags.span(_class='icon-bar')) # btn.add(tags.span(_class='icon-bar')) bar = root.add(tags.div( _class='navbar-collapse collapse', id=node_id, )) if node.title is not None: if hasattr(node.title, 'get_url'): bar.add(tags.a(node.title.text, _class='navbar-brand', href=node.title.get_url())) else: bar.add(tags.a(node.title, _class='navbar-brand', href='/')) bar_list = bar.add(tags.ul(_class='nav navbar-nav')) for item in node.items: bar_list.add(self.visit(item)) return root
def visit_Navbar(self, node): # create a navbar id that is somewhat fixed, but do not leak any # information about memory contents to the outside node_id = self.id or sha1(str(id(node)).encode()).hexdigest() root = tags.nav() if self.html5 else tags.div(role="navigation") root["class"] = "navbar navbar-default" cont = root.add(tags.div(_class="container-fluid")) # collapse button header = cont.add(tags.div(_class="navbar-header")) btn = header.add(tags.button()) btn["type"] = "button" btn["class"] = "navbar-toggle collapsed" btn["data-toggle"] = "collapse" btn["data-target"] = "#" + node_id btn["aria-expanded"] = "false" btn["aria-controls"] = "navbar" btn.add(tags.span("Toggle navigation", _class="sr-only")) btn.add(tags.span(_class="icon-bar")) btn.add(tags.span(_class="icon-bar")) btn.add(tags.span(_class="icon-bar")) # title may also have a 'get_url()' method, in which case we render # a brand-link if node.title is not None: if hasattr(node.title, "get_url"): header.add(tags.a(node.title.text, _class="navbar-brand", href=node.title.get_url())) else: header.add(tags.span(node.title, _class="navbar-brand")) bar = cont.add(tags.div(_class="navbar-collapse collapse", id=node_id)) bar_list = bar.add(tags.ul(_class="nav navbar-nav")) for item in node.items: bar_list.add(self.visit(item)) return root
def to_tag(self): tag = aside(_class="hidden md:flex bg-dark w-44 pt-5 sm:mt-0") _nav = nav() for item in self.items: _item = div(data_action="click->collapse#unhide", data_controller="collapse") lev1 = a( _class=("flex w-44 items-center py-2 pl-2 mt-2 " "text-white border-r-4 border-gray-100 " "hover:bg-cgrey_200 hover:border-white "), href="#", data_turbo="false", data_collapse_target="levelone", ) icon = IconFiles().to_tag() _span = span(item["text"], _class="mx-4 font-medium") lev1.add(icon, _span) if "subheaders" in item: for subitem in item["subheaders"]: style = "flex w-44 items-center py-2 pl-10 text-white bg-cgrey_200 hover:text-dark border-t-2" if item["text"] == self.selected.get("lev1"): if subitem["text"] == self.selected.get("lev2"): style += " selected" else: style += " hidden" lev2 = a( _class=style, href=subitem["href"], data_collapse_target="leveltwo", ) _span = span(subitem["text"], _class="mx-4") lev2.add(_span) lev1.add(lev2) _item.add(lev1) _nav.add(_item) tag.add(_nav) return tag
def report_header(self, theme='lux', highlight_color='#f1c40f', navbar_bg='primary', custom_css='', **kwargs): """ Controls the link and script tags in the head. This method should always be called at the top :param str theme: Name of any bootswatch theme. Default is lux :param str highlight_color: any rgb color. default is #f1c40f :param str script: warg Pass additional JS/jquery to add to header :param str custom_css: Pass additional custom CSS. This is in the header, and controls style for the whole report :param str navbar_bg: Controls the color of the navbar. :param bool bootstrap: Set to True to get default bootstrap theme. Does not work with local files :return: The head tag for the report. Example showing how to change the default theme: >>> r = report.report_header(theme='flatly') """ if len(self.report_name) > 40: logging.warning('A report_name greater than 40 characters can \ can cause the navbar to expand and break some functionality.') with self.document.head as report_head: # link and script builder for bootstrap 4 tag.comment('Created using reportng by securisec') tag.meta(charset="utf-8", name="viewport", content="width=device-width, initial-scale=1") # main style components tag.script(src=rng.JSCSS.jquery) tag.script(src=rng.JSCSS.popper_js) tag.script(src=rng.JSCSS.bs4_js) if not self.search == False: tag.script(src=rng.JSCSS.mark_js) # JS for tooltip tag.command('JS for tooltip') tag.script(raw(rng.JSCustom.tooltip_js)) # JS for mark_js tag.comment('JS for mark.js') tag.script(raw(rng.JSCustom.markjs_script)) # JS to populate the navbar dropdown tag.comment('JS to populate the navbar dropdown') tag.script(raw(rng.JSCustom.populate_navbar_onload)) # script that allows for smooth scrolling and adds padding for navbar tag.comment( 'script that allows for smooth scrolling and adds padding for navbar' ) tag.script(raw(rng.JSCustom.smoothscroll_navbar_pad)) # js to filter in the dropdown menu tag.comment('js to filter in the dropdown menu') tag.script(raw(rng.JSCustom.dropdown_filter)) # user insterted JS if 'script' in kwargs: tag.comment('User inserted JS') tag.script(raw(kwargs.get('script'))) # bootswatch style sheets tag.comment('style sheets') if 'bootstrap' in kwargs: if kwargs['bootstrap']: bootswatch = 'https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css' elif theme != 'lux': bootswatch = "https://bootswatch.com/4/%s/bootstrap.min.css" % theme else: bootswatch = rng.JSCSS.bootswatch tag.link(rel="stylesheet", type="text/css", href=bootswatch, id='bootswatch') tag.link(href=rng.JSCSS.font_awesome, rel="stylesheet") # constructing this way to avoid loading un needed js and css # css for asciinema if self.asciinema == True: tag.comment('css for asciinema') tag.link(rel="stylesheet", type="text/css", href=rng.JSCSS.asciinema_css) # css and js for highlight.js if self.code == True: tag.comment('css and js for highlight.js') tag.link(rel="stylesheet", href=rng.JSCSS.highlightjs_css) tag.script(src=rng.JSCSS.highlightjs_js) tag.script( raw(""" hljs.initHighlightingOnLoad(); """)) # script for progress bar if self.pbar == True: tag.comment('js for progress bar') tag.script(src=rng.JSCSS.progressbar_js) tag.script(raw(rng.JSCustom.progress_bar)) # search highlight color control tag.comment('search highlight color control') # tag.style('span.highlight{background: %s;}' % # highlight_color) tag.style( raw(""" mark {background: %s;} mark.current {background: orangered;} """ % highlight_color)) if custom_css != '': tag.comment('Custom CSS starts here') tag.style(raw(custom_css)) # Navbar on top with 2 margin to seperate from first jumbotron. add class mb-2 with tag.nav( _class= "navbar navbar-expand-lg navbar-dark bg-%s sticky-top" % rng.HelperFunctions.color_to_tag(navbar_bg)): tag.a(self.brand, _class="navbar-brand", href="#") # sets the report title on the navbar tag.span(self.report_name, _class="navbar-text text-secondary") # theme previewer if self.theme_preview: tag.comment('Theme previewer') raw(rng.CustomHTML.themes_preview) # Button for responsive navbar with tag.button(_class="navbar-toggler", type="button", data_toggle="collapse", data_target="#navbarid", aria_controls="navbarColor01", aria_expanded="false", aria_label="Toggle navigation"): tag.span(_class="navbar-toggler-icon") # Search box and button on navbar # make sure to include the word context to div/p tags to make it searchable with tag.div(_class= "navbar-collapse collapse justify-content-md-end", id="navbarid"): # ul class to house the navbar navigation items with tag.ul(_class="navbar-nav"): with tag.li(_class="nav-item"): # add dropdown menu to house h1 tags from sections with tag.div(_class="dropdown"): tag.button( 'sections', _class= "btn btn-secondary btn-block dropdown-toggle", type="button", id="dropdownMenuButton", data_toggle="dropdown", aria_haspopup="true", aria_expanded="false") with tag.ul( _class= "dropdown-menu dropdown-menu-right", aria_labelledby="dropdownMenuButton", id="ddmenu", style= "max-height: 300px; height: auto; overflow: scroll" ): # input box for filtering dropdown tag.input(_class="form-control-sm", id="ddfilter", type="text", placeholder="Filter..") # highlight box form starts here # input for search box if not self.search == False: tag.input(_class="form-control mr-sm-2", type="search", placeholder="Search", data_toggle="tooltip", data_placement="bottom", title="Regex capable. Case sensitive.") # Show search hit count tag.span( "0", id="searchcount", style= "color:%s; font-size: initial; padding-right: 8; align-self: center;" % highlight_color) raw(""" <button data-search="next" class="btn btn-sm btn-secondary">↓</button> <button data-search="prev" class="btn btn-sm btn-secondary">↑</button> """ # <button data-search="clear" class="btn btn-sm btn-secondary">✖</button> ) if self.theme_preview: # theme preview jquery tag.comment('theme preview jquery') tag.script(raw(rng.JSCustom.themes_preview)) return str(report_head)
def visit_Navbar(self, node): root = tags.div() root['class'] = 'navbar-fixed-top' node_id = self.id or sha1(str(id(node)).encode()).hexdigest() top = root.add(tags.nav()) top['class'] = 'navbar navbar-default' top['id'] = 'navbar-top' container = top.add(tags.div(_class='container')) header = container.add(tags.div(_class='navbar-header')) button = header.add(tags.button()) button['type'] = 'button' button['class'] = 'navbar-toggle collapsed' button['data-toggle'] = 'collapse' button['data-target'] = '#' + node_id button['aria-expanded'] = 'false' button['aria-controls'] = 'navbar' button.add(tags.span('Toggle navigation', _class='sr-only')) button.add(tags.span(_class='icon-bar')) button.add(tags.span(_class='icon-bar')) button.add(tags.span(_class='icon-bar')) if node.title is not None: if hasattr(node.title, 'get_url'): header.add( tags.a(node.title.text, _class='navbar-brand', href=node.title.get_url())) else: header.add(tags.span(node.title, _class='navbar-brand')) bar = container.add( tags.div(_class='navbar-collapse collapse', id=node_id)) bar_left = bar.add( tags.ul(_class='nav navbar-nav navbar-left visible-xs')) bar_right = bar.add( tags.ul(_class='nav navbar-nav navbar-right hidden-xs')) for item in node.items: bar_left.add(self.visit(item)) if not getattr(item, 'left', True): bar_right.add(self.visit(item)) spacer = root.add(tags.div()) spacer['id'] = 'navbar-spacer' bottom = root.add(tags.nav()) bottom['class'] = 'navbar navbar-inverse hidden-xs' bottom['id'] = 'navbar-bottom' container = bottom.add(tags.div(_class='container')) bar = container.add(tags.div(_class='navbar-collapse collapse')) bar_left = bar.add(tags.ul(_class='nav navbar-nav navbar-left')) for item in node.items: if getattr(item, 'left', True): bar_left.add(self.visit(item)) return root