Repository: getpelican/pelican

Issue:
markdown article with multiple category definitions is poorly handled
@avaris

If an article (in this case written in markdown) has multiple `Category:` definitions, then pelican bombs out with a not-too-obvious error message. While this is something the user should fix, it would be more useful to have a more helpful error message.

```
CRITICAL: coercing to Unicode: need string or buffer, list found
Traceback (most recent call last):
  File "/Users/jchen/.venvs/burrito.sh/bin/pelican", line 11, in <module>
    sys.exit(main())
  File "/Users/jchen/.venvs/burrito.sh/lib/python2.7/site-packages/pelican/__init__.py", line 419, in main
    pelican.run()
  File "/Users/jchen/.venvs/burrito.sh/lib/python2.7/site-packages/pelican/__init__.py", line 167, in run
    p.generate_context()
  File "/Users/jchen/.venvs/burrito.sh/lib/python2.7/site-packages/pelican/generators.py", line 508, in generate_context
    self.categories[article.category].append(article)
  File "/Users/jchen/.venvs/burrito.sh/lib/python2.7/site-packages/pelican/urlwrappers.py", line 48, in __eq__
    return self._key() == self._normalize_key(other)
  File "/Users/jchen/.venvs/burrito.sh/lib/python2.7/site-packages/pelican/urlwrappers.py", line 45, in _normalize_key
    return six.text_type(slugify(key, subs))
  File "/Users/jchen/.venvs/burrito.sh/lib/python2.7/site-packages/pelican/utils.py", line 234, in slugify
    value = Markup(value).striptags()
  File "/Users/jchen/.venvs/burrito.sh/lib/python2.7/site-packages/markupsafe/__init__.py", line 74, in __new__
    return text_type.__new__(cls, base)
TypeError: coercing to Unicode: need string or buffer, list found
```

from IRC:

```
23:30 < jchen> hi, how am I supposed to debug this? CRITICAL: coercing to Unicode: need string or buffer, list found
23:31 < jchen> the trace is here: https://gist.github.com/fly/a9d4c28583e6c19227f5
23:32 < Avaris> jchen: you defined `category` metadata multiple times in a .md file
23:33 < jchen> Avaris: that's it, thanks :)
23:34 < Avaris> and i was going to make a PR for that... i am forgetful these days.
23:34 < justmay> It would indeed be nice to catch those kinds of things :^)
23:34 < Avaris> jchen: can you open an issue for it so that my slippery mind has no excuses?
```



Discussion:

Resolving patch:
diff --git a/pelican/readers.py b/pelican/readers.py
--- a/pelican/readers.py
+++ b/pelican/readers.py
@@ -201,6 +201,7 @@ def __init__(self, *args, **kwargs):
         self.extensions = list(self.settings['MD_EXTENSIONS'])
         if 'meta' not in self.extensions:
             self.extensions.append('meta')
+        self._source_path = None
 
     def _parse_metadata(self, meta):
         """Return the dict containing document metadata"""
@@ -215,6 +216,11 @@ def _parse_metadata(self, meta):
                 self._md.reset()
                 summary = self._md.convert(summary_values)
                 output[name] = self.process_metadata(name, summary)
+            elif name in METADATA_PROCESSORS:
+                if len(value) > 1:
+                    logger.warning('Duplicate definition of `%s` '
+                        'for %s. Using first one.', name, self._source_path)
+                output[name] = self.process_metadata(name, value[0])
             elif len(value) > 1:
                 # handle list metadata as list of string
                 output[name] = self.process_metadata(name, value)
@@ -226,6 +232,7 @@ def _parse_metadata(self, meta):
     def read(self, source_path):
         """Parse content and metadata of markdown files"""
 
+        self._source_path = source_path
         self._md = Markdown(extensions=self.extensions)
         with pelican_open(source_path) as text:
             content = self._md.convert(text)


Test patch: