def test_per_template_pagination_affected(self): settings = get_settings() settings['TEMPLATE_PAGINATION'] = { 'articles' : 5 } paginator = Paginator('articles', 'articles', self.articles, settings) self.assertTrue(paginator._get_num_pages() > 1)
def test_custom_pagination_pattern_last_page(self): from pelican.paginator import PaginationRule settings = get_settings() settings['PAGINATION_PATTERNS'] = [ PaginationRule(*r) for r in [ (1, '/{url}1/', '{base_name}/1/index.html'), (2, '/{url}{number}/', '{base_name}/{number}/index.html'), (-1, '/{url}', '{base_name}/index.html'), ] ] self.page_kwargs['metadata']['author'] = Author('Blogger', settings) object_list = [ Article(**self.page_kwargs), Article(**self.page_kwargs), Article(**self.page_kwargs) ] paginator = Paginator('blog/index.html', '//blog.my.site/', object_list, settings, 1) # The URL *has to* stay absolute (with // in the front), so verify that page1 = paginator.page(1) self.assertEqual(page1.save_as, 'blog/1/index.html') self.assertEqual(page1.url, '//blog.my.site/1/') page2 = paginator.page(2) self.assertEqual(page2.save_as, 'blog/2/index.html') self.assertEqual(page2.url, '//blog.my.site/2/') page3 = paginator.page(3) self.assertEqual(page3.save_as, 'blog/index.html') self.assertEqual(page3.url, '//blog.my.site/')
def test_default_pagination_value(self): settings = get_settings() settings['DEFAULT_PAGINATION'] = 5 paginator = Paginator('articles', 'articles', self.articles, settings) self.assertTrue(paginator._get_num_pages() > 1)
def test_per_template_pagination_unaffected(self): settings = get_settings() settings['TEMPLATE_PAGINATION'] = { 'articles' : 5 } paginator = Paginator('index', 'index', self.articles, settings) self.assertEqual(paginator._get_num_pages(), 1)
def test_save_as_preservation(self): settings = get_settings() # fix up pagination rules from pelican.paginator import PaginationRule pagination_rules = [ PaginationRule(*r) for r in settings.get("PAGINATION_PATTERNS", DEFAULT_CONFIG["PAGINATION_PATTERNS"]) ] settings["PAGINATION_PATTERNS"] = sorted(pagination_rules, key=lambda r: r[0]) self.page_kwargs["metadata"]["author"] = Author("Blogger", settings) object_list = [Article(**self.page_kwargs), Article(**self.page_kwargs)] paginator = Paginator("foobar.foo", object_list, settings) page = paginator.page(1) self.assertEqual(page.save_as, "foobar.foo")
def write_file(self, name, template, context, relative_urls=False, paginated=None, override_output=False, **kwargs): if not name: logger.debug("No name, skipping") return # make context if paginated: paginators = { key: Paginator(name, val, self.settings) for key, val in paginated.items() } for page_num in range(list(paginators.values())[0].num_pages): local_kwargs = self._paginate(kwargs, paginators, page_num) page = list(paginators.values())[0].page(page_num + 1) localcontext = self._make_localcontext(context, page.save_as, local_kwargs) self._write_file(template, localcontext, page.save_as) else: localcontext = self._make_localcontext(context, name, kwargs) self._write_file(template, localcontext, name)
def test_custom_pagination_pattern(self): from pelican.paginator import PaginationRule settings = get_settings() settings['PAGINATION_PATTERNS'] = [PaginationRule(*r) for r in [ (1, '/{url}', '{base_name}/index.html'), (2, '/{url}{number}/', '{base_name}/{number}/index.html') ]] self.page_kwargs['metadata']['author'] = Author('Blogger', settings) object_list = [Article(**self.page_kwargs), Article(**self.page_kwargs)] paginator = Paginator('blog/index.html', '//blog.my.site/', object_list, settings, 1) page1 = paginator.page(1) self.assertEqual(page1.save_as, 'blog/index.html') self.assertEqual(page1.url, '//blog.my.site/') page2 = paginator.page(2) self.assertEqual(page2.save_as, 'blog/2/index.html') self.assertEqual(page2.url, '//blog.my.site/2/')
def test_save_as_preservation(self): settings = get_settings() # fix up pagination rules from pelican.paginator import PaginationRule pagination_rules = [ PaginationRule(*r) for r in settings.get( 'PAGINATION_PATTERNS', DEFAULT_CONFIG['PAGINATION_PATTERNS'], ) ] settings['PAGINATION_PATTERNS'] = sorted( pagination_rules, key=lambda r: r[0], ) object_list = [Article(**self.page_kwargs), Article(**self.page_kwargs)] paginator = Paginator('foobar.foo', object_list, settings) page = paginator.page(1) self.assertEqual(page.save_as, 'foobar.foo')
def test_save_as_preservation(self): settings = get_settings() # fix up pagination rules from pelican.paginator import PaginationRule pagination_rules = [ PaginationRule(*r) for r in settings.get( 'PAGINATION_PATTERNS', DEFAULT_CONFIG['PAGINATION_PATTERNS'], ) ] settings['PAGINATION_PATTERNS'] = sorted( pagination_rules, key=lambda r: r[0], ) object_list = [ Article(**self.page_kwargs), Article(**self.page_kwargs) ] paginator = Paginator('foobar.foo', object_list, settings) page = paginator.page(1) self.assertEqual(page.save_as, 'foobar.foo')
def test_custom_pagination_pattern(self): from pelican.paginator import PaginationRule settings = get_settings() settings['PAGINATION_PATTERNS'] = [ PaginationRule(*r) for r in [(1, '/{url}', '{base_name}/index.html'), (2, '/{url}{number}/', '{base_name}/{number}/index.html')] ] self.page_kwargs['metadata']['author'] = Author('Blogger', settings) object_list = [ Article(**self.page_kwargs), Article(**self.page_kwargs) ] paginator = Paginator('blog/index.html', '//blog.my.site/', object_list, settings, 1) page1 = paginator.page(1) self.assertEqual(page1.save_as, 'blog/index.html') self.assertEqual(page1.url, '//blog.my.site/') page2 = paginator.page(2) self.assertEqual(page2.save_as, 'blog/2/index.html') self.assertEqual(page2.url, '//blog.my.site/2/')
def write_file(self, name, template, context, relative_urls=True, paginated=None, **kwargs): """Render the template and write the file. :param name: name of the file to output :param template: template to use to generate the content :param context: dict to pass to the templates. :param relative_urls: use relative urls or absolutes ones :param paginated: dict of article list to paginate - must have the same length (same list in different orders) :param **kwargs: additional variables to pass to the templates """ def _write_file(template, localcontext, output_path, name): """Render the template write the file.""" old_locale = locale.setlocale(locale.LC_ALL) locale.setlocale(locale.LC_ALL, 'C') try: output = template.render(localcontext) finally: locale.setlocale(locale.LC_ALL, old_locale) filename = os.sep.join((output_path, name)) try: os.makedirs(os.path.dirname(filename)) except Exception: pass with open(filename, 'w', encoding='utf-8') as f: f.write(output) info(u'writing %s' % filename) localcontext = context.copy() if relative_urls: localcontext['SITEURL'] = get_relative_path(name) localcontext.update(kwargs) if relative_urls: self.update_context_contents(name, localcontext) # check paginated paginated = paginated or {} if paginated: # pagination needed, init paginators paginators = {} for key in paginated.iterkeys(): object_list = paginated[key] if self.settings.get('WITH_PAGINATION'): paginators[key] = Paginator( object_list, self.settings.get('DEFAULT_PAGINATION'), self.settings.get('DEFAULT_ORPHANS')) else: paginators[key] = Paginator(object_list, len(object_list), 0) # generated pages, and write for page_num in range(paginators.values()[0].num_pages): paginated_localcontext = localcontext.copy() paginated_name = name for key in paginators.iterkeys(): paginator = paginators[key] page = paginator.page(page_num + 1) paginated_localcontext.update({ '%s_paginator' % key: paginator, '%s_page' % key: page }) if page_num > 0: ext = '.' + paginated_name.rsplit('.')[-1] paginated_name = paginated_name.replace( ext, '%s%s' % (page_num + 1, ext)) _write_file(template, paginated_localcontext, self.output_path, paginated_name) else: # no pagination _write_file(template, localcontext, self.output_path, name)
def write_file(self, name, template, context, relative_urls=False, paginated=None, template_name=None, override_output=False, url=None, **kwargs): """Render the template and write the file. :param name: name of the file to output :param template: template to use to generate the content :param context: dict to pass to the templates. :param relative_urls: use relative urls or absolutes ones :param paginated: dict of article list to paginate - must have the same length (same list in different orders) :param template_name: the template name, for pagination :param override_output: boolean telling if we can override previous output with the same name (and if next files written with the same name should be skipped to keep that one) :param url: url of the file (needed by the paginator) :param **kwargs: additional variables to pass to the templates """ if name is False or \ name == "" or \ not is_selected_for_writing(self.settings, os.path.join(self.output_path, name)): return elif not name: # other stuff, just return for now return def _write_file(template, localcontext, output_path, name, override): """Render the template write the file.""" # set localsiteurl for context so that Contents can adjust links if localcontext['localsiteurl']: context['localsiteurl'] = localcontext['localsiteurl'] output = template.render(localcontext) path = sanitised_join(output_path, name) try: os.makedirs(os.path.dirname(path)) except Exception: pass with self._open_w(path, 'utf-8', override=override) as f: f.write(output) logger.info('Writing %s', path) # Send a signal to say we're writing a file with some specific # local context. signals.content_written.send(path, context=localcontext) def _get_localcontext(context, name, kwargs, relative_urls): localcontext = context.copy() localcontext['localsiteurl'] = localcontext.get( 'localsiteurl', None) if relative_urls: relative_url = path_to_url(get_relative_path(name)) localcontext['SITEURL'] = relative_url localcontext['localsiteurl'] = relative_url localcontext['output_file'] = name localcontext.update(kwargs) return localcontext if paginated is None: paginated = {key: val for key, val in kwargs.items() if key in {'articles', 'dates'}} # pagination if paginated and template_name in self.settings['PAGINATED_TEMPLATES']: # pagination needed per_page = self.settings['PAGINATED_TEMPLATES'][template_name] \ or self.settings['DEFAULT_PAGINATION'] # init paginators paginators = {key: Paginator(name, url, val, self.settings, per_page) for key, val in paginated.items()} # generated pages, and write for page_num in range(list(paginators.values())[0].num_pages): paginated_kwargs = kwargs.copy() for key in paginators.keys(): paginator = paginators[key] previous_page = paginator.page(page_num) \ if page_num > 0 else None page = paginator.page(page_num + 1) next_page = paginator.page(page_num + 2) \ if page_num + 1 < paginator.num_pages else None paginated_kwargs.update( {'%s_paginator' % key: paginator, '%s_page' % key: page, '%s_previous_page' % key: previous_page, '%s_next_page' % key: next_page}) localcontext = _get_localcontext( context, page.save_as, paginated_kwargs, relative_urls) _write_file(template, localcontext, self.output_path, page.save_as, override_output) else: # no pagination localcontext = _get_localcontext( context, name, kwargs, relative_urls) _write_file(template, localcontext, self.output_path, name, override_output)
def write_file(self, name, template, context, relative_urls=False, paginated=None, **kwargs): """Render the template and write the file. :param name: name of the file to output :param template: template to use to generate the content :param context: dict to pass to the templates. :param relative_urls: use relative urls or absolutes ones :param paginated: dict of article list to paginate - must have the same length (same list in different orders) :param **kwargs: additional variables to pass to the templates """ if name is False: return elif not name: # other stuff, just return for now return def _write_file(template, localcontext, output_path, name): """Render the template write the file.""" old_locale = locale.setlocale(locale.LC_ALL) locale.setlocale(locale.LC_ALL, str('C')) try: output = template.render(localcontext) finally: locale.setlocale(locale.LC_ALL, old_locale) path = os.path.join(output_path, name) try: os.makedirs(os.path.dirname(path)) except Exception: pass with open(path, 'w', encoding='utf-8') as f: f.write(output) logger.info('writing {}'.format(path)) localcontext = context.copy() if relative_urls: relative_url = path_to_url(get_relative_path(name)) context['localsiteurl'] = relative_url localcontext['SITEURL'] = relative_url localcontext['output_file'] = name localcontext.update(kwargs) # check paginated paginated = paginated or {} if paginated: # pagination needed, init paginators paginators = {} for key in paginated.keys(): object_list = paginated[key] if self.settings.get('DEFAULT_PAGINATION'): paginators[key] = Paginator( object_list, self.settings.get('DEFAULT_PAGINATION'), self.settings.get('DEFAULT_ORPHANS')) else: paginators[key] = Paginator(object_list, len(object_list)) # generated pages, and write name_root, ext = os.path.splitext(name) for page_num in range(list(paginators.values())[0].num_pages): paginated_localcontext = localcontext.copy() for key in paginators.keys(): paginator = paginators[key] page = paginator.page(page_num + 1) paginated_localcontext.update({ '%s_paginator' % key: paginator, '%s_page' % key: page }) if page_num > 0: paginated_name = '%s%s%s' % (name_root, page_num + 1, ext) else: paginated_name = name _write_file(template, paginated_localcontext, self.output_path, paginated_name) else: # no pagination _write_file(template, localcontext, self.output_path, name)
def write_file(self, name, template, context, relative_urls=False, paginated=None, override_output=False, **kwargs): """Render the template and write the file. :param name: name of the file to output :param template: template to use to generate the content :param context: dict to pass to the templates. :param relative_urls: use relative urls or absolutes ones :param paginated: dict of article list to paginate - must have the same length (same list in different orders) :param override_output: boolean telling if we can override previous output with the same name (and if next files written with the same name should be skipped to keep that one) :param **kwargs: additional variables to pass to the templates """ if name is False: return elif not name: # other stuff, just return for now return def _write_file(template, localcontext, output_path, name, override): """Render the template write the file.""" old_locale = locale.setlocale(locale.LC_ALL) locale.setlocale(locale.LC_ALL, str('C')) try: output = template.render(localcontext) finally: locale.setlocale(locale.LC_ALL, old_locale) path = os.path.join(output_path, name) try: os.makedirs(os.path.dirname(path)) except Exception: pass with self._open_w(path, 'utf-8', override=override) as f: f.write(output) logger.info('writing {}'.format(path)) # Send a signal to say we're writing a file with some specific # local context. signals.content_written.send(path, context=localcontext) localcontext = context.copy() if relative_urls: relative_url = path_to_url(get_relative_path(name)) context['localsiteurl'] = relative_url localcontext['SITEURL'] = relative_url localcontext['output_file'] = name localcontext.update(kwargs) # check paginated paginated = paginated or {} if paginated: name_root = os.path.splitext(name)[0] # pagination needed, init paginators paginators = {} for key in paginated.keys(): object_list = paginated[key] paginators[key] = Paginator( name_root, object_list, self.settings, ) # generated pages, and write for page_num in range(list(paginators.values())[0].num_pages): paginated_localcontext = localcontext.copy() for key in paginators.keys(): paginator = paginators[key] previous_page = paginator.page(page_num) \ if page_num > 0 else None page = paginator.page(page_num + 1) next_page = paginator.page(page_num + 2) \ if page_num + 1 < paginator.num_pages else None paginated_localcontext.update( {'%s_paginator' % key: paginator, '%s_page' % key: page, '%s_previous_page' % key: previous_page, '%s_next_page' % key: next_page}) _write_file(template, paginated_localcontext, self.output_path, page.save_as, override_output) else: # no pagination _write_file(template, localcontext, self.output_path, name, override_output)
def test_default_pagination_default(self): settings = get_settings() paginator = Paginator('index', 'index', self.articles, settings) self.assertEqual(paginator._get_num_pages(), 1)
def write_file(self, name, template, context, relative_urls=False, paginated=None, override_output=False, **kwargs): """Render the template and write the file. :param name: name of the file to output :param template: template to use to generate the content :param context: dict to pass to the templates. :param relative_urls: use relative urls or absolutes ones :param paginated: dict of article list to paginate - must have the same length (same list in different orders) :param override_output: boolean telling if we can override previous output with the same name (and if next files written with the same name should be skipped to keep that one) :param **kwargs: additional variables to pass to the templates """ if name is False or name == "" or\ not is_selected_for_writing(self.settings,\ os.path.join(self.output_path, name)): return elif not name: # other stuff, just return for now return def _render_using_plim(filename, localcontext): """Render the template using Plim.""" root_dir = os.path.dirname(os.path.abspath(filename)) template_file = os.path.basename(filename) lookup = mako.lookup.TemplateLookup( directories=[root_dir], input_encoding='utf-8', output_encoding='utf-8', preprocessor=plim.preprocessor, strict_undefined=True, default_filters=['trim']) output = lookup.get_template(template_file).render_unicode( **localcontext) if ('SLIM_OPTIONS' in self.settings and 'PRETTYIFY' in self.settings['SLIM_OPTIONS'] and self.settings['SLIM_OPTIONS']['PRETTYIFY']): output = bs(output, 'html.parser').prettify() # prettify the html else: output = minify(output) # minify the html return output def _write_file(template, localcontext, output_path, name, override): """Render the template write the file.""" # set localsiteurl for context so that Contents can adjust links if localcontext['localsiteurl']: context['localsiteurl'] = localcontext['localsiteurl'] output = _render_using_plim(template.filename, localcontext) # output = template.render(localcontext) # render using jinja2 path = os.path.join(output_path, name) try: os.makedirs(os.path.dirname(path)) except Exception: pass with self._open_w(path, 'utf-8', override=override) as f: f.write(output) logger.info('Writing %s', path) # Send a signal to say we're writing a file with some specific # local context. signals.content_written.send(path, context=localcontext) def _get_localcontext(context, name, kwargs, relative_urls): localcontext = context.copy() localcontext['localsiteurl'] = localcontext.get( 'localsiteurl', None) if relative_urls: relative_url = path_to_url(get_relative_path(name)) localcontext['SITEURL'] = relative_url localcontext['localsiteurl'] = relative_url localcontext['output_file'] = name localcontext.update(kwargs) return localcontext # pagination if paginated: # pagination needed, init paginators paginators = { key: Paginator(name, val, self.settings) for key, val in paginated.items() } # generated pages, and write for page_num in range(list(paginators.values())[0].num_pages): paginated_kwargs = kwargs.copy() for key in paginators.keys(): paginator = paginators[key] previous_page = paginator.page(page_num) \ if page_num > 0 else None page = paginator.page(page_num + 1) next_page = paginator.page(page_num + 2) \ if page_num + 1 < paginator.num_pages else None paginated_kwargs.update({ '%s_paginator' % key: paginator, '%s_page' % key: page, '%s_previous_page' % key: previous_page, '%s_next_page' % key: next_page }) localcontext = _get_localcontext(context, page.save_as, paginated_kwargs, relative_urls) _write_file(template, localcontext, self.output_path, page.save_as, override_output) else: # no pagination localcontext = _get_localcontext(context, name, kwargs, relative_urls) _write_file(template, localcontext, self.output_path, name, override_output)