diff --git a/pelican/tests/test_utils.py b/pelican/tests/test_utils.py index 8dfc0b9b..040707ca 100644 --- a/pelican/tests/test_utils.py +++ b/pelican/tests/test_utils.py @@ -216,46 +216,62 @@ class TestUtils(LoggedTestCase): "∫dx " * 20 + '…') def test_process_translations(self): + fr_articles = [] + en_articles = [] + # create a bunch of articles - # 1: no translation metadata - fr_article1 = get_article(lang='fr', slug='yay', title='Un titre', - content='en français') - en_article1 = get_article(lang='en', slug='yay', title='A title', - content='in english') - # 2: reverse which one is the translation thanks to metadata - fr_article2 = get_article(lang='fr', slug='yay2', title='Un titre', - content='en français') - en_article2 = get_article(lang='en', slug='yay2', title='A title', - content='in english', - extra_metadata={'translation': 'true'}) + # 0: no translation metadata + fr_articles.append(get_article(lang='fr', slug='yay0', title='Titre', + content='en français')) + en_articles.append(get_article(lang='en', slug='yay0', title='Title', + content='in english')) + # 1: translation metadata on default lang + fr_articles.append(get_article(lang='fr', slug='yay1', title='Titre', + content='en français')) + en_articles.append(get_article(lang='en', slug='yay1', title='Title', + content='in english', + extra_metadata={'translation': 'true'})) + # 2: translation metadata not on default lang + fr_articles.append(get_article(lang='fr', slug='yay2', title='Titre', + content='en français', + extra_metadata={'translation': 'true'})) + en_articles.append(get_article(lang='en', slug='yay2', title='Title', + content='in english')) # 3: back to default language detection if all items have the # translation metadata - fr_article3 = get_article(lang='fr', slug='yay3', title='Un titre', - content='en français', - extra_metadata={'translation': 'yep'}) - en_article3 = get_article(lang='en', slug='yay3', title='A title', - content='in english', - extra_metadata={'translation': 'yes'}) + fr_articles.append(get_article(lang='fr', slug='yay3', title='Titre', + content='en français', + extra_metadata={'translation': 'yep'})) + en_articles.append(get_article(lang='en', slug='yay3', title='Title', + content='in english', + extra_metadata={'translation': 'yes'})) - articles = [fr_article1, en_article1, fr_article2, en_article2, - fr_article3, en_article3] + # try adding articles in both orders + for lang0_articles, lang1_articles in ((fr_articles, en_articles), + (en_articles, fr_articles)): + articles = lang0_articles + lang1_articles - index, trans = utils.process_translations(articles) + index, trans = utils.process_translations(articles) - self.assertIn(en_article1, index) - self.assertIn(fr_article1, trans) - self.assertNotIn(en_article1, trans) - self.assertNotIn(fr_article1, index) + self.assertIn(en_articles[0], index) + self.assertIn(fr_articles[0], trans) + self.assertNotIn(en_articles[0], trans) + self.assertNotIn(fr_articles[0], index) - self.assertIn(fr_article2, index) - self.assertIn(en_article2, trans) - self.assertNotIn(fr_article2, trans) - self.assertNotIn(en_article2, index) + self.assertIn(fr_articles[1], index) + self.assertIn(en_articles[1], trans) + self.assertNotIn(fr_articles[1], trans) + self.assertNotIn(en_articles[1], index) - self.assertIn(en_article3, index) - self.assertIn(fr_article3, trans) - self.assertNotIn(en_article3, trans) - self.assertNotIn(fr_article3, index) + self.assertIn(en_articles[2], index) + self.assertIn(fr_articles[2], trans) + self.assertNotIn(en_articles[2], trans) + self.assertNotIn(fr_articles[2], index) + + self.assertIn(en_articles[3], index) + self.assertIn(fr_articles[3], trans) + self.assertNotIn(en_articles[3], trans) + self.assertNotIn(fr_articles[3], index) def test_watchers(self): # Test if file changes are correctly detected diff --git a/pelican/utils.py b/pelican/utils.py index f1558fda..9d780039 100644 --- a/pelican/utils.py +++ b/pelican/utils.py @@ -625,43 +625,57 @@ def process_translations(content_list, order_by=None): index = [] translations = [] + def _warn_source_paths(msg, items, *extra): + args = [len(items)] + args.extend(extra) + args.extend((x.source_path for x in items)) + logger.warning('{}: {}'.format(msg, '\n%s' * len(items)), *args) + for slug, items in grouped_by_slugs: items = list(items) - # items with `translation` metadata will be used as translations... - default_lang_items = list(filter( - lambda i: - i.metadata.get('translation', 'false').lower() == 'false', - items)) - # ...unless all items with that slug are translations - if not default_lang_items: - default_lang_items = items + + # display warnings if slug is empty + if not slug: + _warn_source_paths('There are %s items with empty slug', items) # display warnings if several items have the same lang for lang, lang_items in groupby(items, attrgetter('lang')): lang_items = list(lang_items) - len_ = len(lang_items) - if len_ > 1: - logger.warning('There are %s variants of "%s" with lang %s', - len_, slug, lang) - for x in lang_items: - logger.warning('\t%s', x.source_path) + if len(lang_items) > 1: + _warn_source_paths( + 'There are %s items with slug "%s" with lang %s', + lang_items, + slug, + lang) + + # items with `translation` metadata will be used as translations... + candidate_items = list(filter( + lambda i: + i.metadata.get('translation', 'false').lower() == 'false', + items)) + # ...unless all items with that slug are translations + if not candidate_items: + logger.warning('All items with slug "%s" are translations', slug) + candidate_items = items # find items with default language - default_lang_items = list(filter( + original_items = list(filter( attrgetter('in_default_lang'), - default_lang_items)) + candidate_items)) - # if there is no article with default language, take an other one - if not default_lang_items: - default_lang_items = items[:1] + # if there is no article with default language, go back one step + if not original_items: + original_items = candidate_items - if not slug: - logger.warning( - 'Empty slug for %s. You can fix this by ' - 'adding a title or a slug to your content', - default_lang_items[0].source_path) - index.extend(default_lang_items) - translations.extend([x for x in items if x not in default_lang_items]) + # display warning if there are several original items + if len(original_items) > 1: + _warn_source_paths( + 'There are %s original (not translated) items with slug "%s"', + original_items, + slug) + + index.extend(original_items) + translations.extend([x for x in items if x not in original_items]) for a in items: a.translations = [x for x in items if x != a]