We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Atom feeds don't validate with SITEURL containing HTTPS scheme and/or a specific service port.
When SITEURL = 'https://example.com' or 'http://example.com:8080', `writers.py` generates `unique_id` producing wrong 'TAG:' IDs.

A possible fix could be to switch **line 45** from :

``` python
unique_id='tag:%s,%s:%s' % (self.site_url.replace('http://', ''),
                            item.date.date(), item.url),
```

to :

``` python
unique_id='tag:%s,%s:%s' % (re.sub('^https?://(?P<host>.*?)(:\d+)?$','\g<host>',self.site_url),
                            item.date.date(), item.url),
```

Atom feeds don't validate with SITEURL containing HTTPS scheme and/or a specific service port.
When SITEURL = 'https://example.com' or 'http://example.com:8080', `writers.py` generates `unique_id` producing wrong 'TAG:' IDs.

A possible fix could be to switch **line 45** from :

``` python
unique_id='tag:%s,%s:%s' % (self.site_url.replace('http://', ''),
                            item.date.date(), item.url),
```

to :

``` python
unique_id='tag:%s,%s:%s' % (re.sub('^https?://(?P<host>.*?)(:\d+)?$','\g<host>',self.site_url),
                            item.date.date(), item.url),
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pelican/writers.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 from __future__ import with_statement, unicode_literals, print_function
3 import six
4 
5 import os
6 import locale
7 import logging
8 
9 if not six.PY3:
10     from codecs import open
11 
12 from feedgenerator import Atom1Feed, Rss201rev2Feed
13 from jinja2 import Markup
14 
15 from pelican.paginator import Paginator
16 from pelican.utils import get_relative_path, path_to_url, set_date_tzinfo
17 from pelican import signals
18 
19 logger = logging.getLogger(__name__)
20 
21 
22 class Writer(object):
23 
24     def __init__(self, output_path, settings=None):
25         self.output_path = output_path
26         self.reminder = dict()
27         self.settings = settings or {}
28         self._written_files = set()
29         self._overridden_files = set()
30 
31     def _create_new_feed(self, feed_type, context):
32         feed_class = Rss201rev2Feed if feed_type == 'rss' else Atom1Feed
33         sitename = Markup(context['SITENAME']).striptags()
34         feed = feed_class(
35             title=sitename,
36             link=(self.site_url + '/'),
37             feed_url=self.feed_url,
38             description=context.get('SITESUBTITLE', ''))
39         return feed
40 
41     def _add_item_to_the_feed(self, feed, item):
42 
43         title = Markup(item.title).striptags()
44         feed.add_item(
45             title=title,
46             link='%s/%s' % (self.site_url, item.url),
47             unique_id='tag:%s,%s:%s' % (self.site_url.replace('http://', ''),
48                                         item.date.date(), item.url),
49             description=item.get_content(self.site_url),
50             categories=item.tags if hasattr(item, 'tags') else None,
51             author_name=getattr(item, 'author', ''),
52             pubdate=set_date_tzinfo(item.date,
53                 self.settings.get('TIMEZONE', None)))
54 
55     def _open_w(self, filename, encoding, override=False):
56         """Open a file to write some content to it.
57 
58         Exit if we have already written to that file, unless one (and no more
59         than one) of the writes has the override parameter set to True.
60         """
61         if filename in self._overridden_files:
62             if override:
63                 raise RuntimeError('File %s is set to be overridden twice'
64                                     % filename)
65             else:
66                 logger.info('skipping %s' % filename)
67                 filename = os.devnull
68         elif filename in self._written_files:
69             if override:
70                 logger.info('overwriting %s' % filename)
71             else:
72                 raise RuntimeError('File %s is to be overwritten' % filename)
73         if override:
74             self._overridden_files.add(filename)
75         self._written_files.add(filename)
76         return open(filename, 'w', encoding=encoding)
77 
78     def write_feed(self, elements, context, path=None, feed_type='atom'):
79         """Generate a feed with the list of articles provided
80 
81         Return the feed. If no path or output_path is specified, just
82         return the feed object.
83 
84         :param elements: the articles to put on the feed.
85         :param context: the context to get the feed metadata.
86         :param path: the path to output.
87         :param feed_type: the feed type to use (atom or rss)
88         """
89         old_locale = locale.setlocale(locale.LC_ALL)
90         locale.setlocale(locale.LC_ALL, str('C'))
91         try:
92             self.site_url = context.get(
93                 'SITEURL', path_to_url(get_relative_path(path)))
94 
95             self.feed_domain = context.get('FEED_DOMAIN')
96             self.feed_url = '{}/{}'.format(self.feed_domain, path)
97 
98             feed = self._create_new_feed(feed_type, context)
99 
100             max_items = len(elements)
101             if self.settings['FEED_MAX_ITEMS']:
102                 max_items = min(self.settings['FEED_MAX_ITEMS'], max_items)
103             for i in range(max_items):
104                 self._add_item_to_the_feed(feed, elements[i])
105 
106             if path:
107                 complete_path = os.path.join(self.output_path, path)
108                 try:
109                     os.makedirs(os.path.dirname(complete_path))
110                 except Exception:
111                     pass
112 
113                 encoding = 'utf-8' if six.PY3 else None
114                 with self._open_w(complete_path, encoding) as fp:
115                     feed.write(fp, 'utf-8')
116                     logger.info('writing %s' % complete_path)
117             return feed
118         finally:
119             locale.setlocale(locale.LC_ALL, old_locale)
120 
121     def write_file(self, name, template, context, relative_urls=False,
122         paginated=None, override_output=False, **kwargs):
123         """Render the template and write the file.
124 
125         :param name: name of the file to output
126         :param template: template to use to generate the content
127         :param context: dict to pass to the templates.
128         :param relative_urls: use relative urls or absolutes ones
129         :param paginated: dict of article list to paginate - must have the
130             same length (same list in different orders)
131         :param override_output: boolean telling if we can override previous
132             output with the same name (and if next files written with the same
133             name should be skipped to keep that one)
134         :param **kwargs: additional variables to pass to the templates
135         """
136 
137         if name is False:
138             return
139         elif not name:
140             # other stuff, just return for now
141             return
142 
143         def _write_file(template, localcontext, output_path, name, override):
144             """Render the template write the file."""
145             old_locale = locale.setlocale(locale.LC_ALL)
146             locale.setlocale(locale.LC_ALL, str('C'))
147             try:
148                 output = template.render(localcontext)
149             finally:
150                 locale.setlocale(locale.LC_ALL, old_locale)
151             path = os.path.join(output_path, name)
152             try:
153                 os.makedirs(os.path.dirname(path))
154             except Exception:
155                 pass
156 
157             with self._open_w(path, 'utf-8', override=override) as f:
158                 f.write(output)
159             logger.info('writing {}'.format(path))
160 
161             # Send a signal to say we're writing a file with some specific
162             # local context.
163             signals.content_written.send(path, context=localcontext)
164 
165         localcontext = context.copy()
166         if relative_urls:
167             relative_url = path_to_url(get_relative_path(name))
168             context['localsiteurl'] = relative_url
169             localcontext['SITEURL'] = relative_url
170 
171         localcontext['output_file'] = name
172         localcontext.update(kwargs)
173 
174         # check paginated
175         paginated = paginated or {}
176         if paginated:
177             name_root = os.path.splitext(name)[0]
178 
179             # pagination needed, init paginators
180             paginators = {}
181             for key in paginated.keys():
182                 object_list = paginated[key]
183 
184                 paginators[key] = Paginator(
185                     name_root,
186                     object_list,
187                     self.settings,
188                 )
189 
190             # generated pages, and write
191             for page_num in range(list(paginators.values())[0].num_pages):
192                 paginated_localcontext = localcontext.copy()
193                 for key in paginators.keys():
194                     paginator = paginators[key]
195                     previous_page = paginator.page(page_num) \
196                             if page_num > 0 else None
197                     page = paginator.page(page_num + 1)
198                     next_page = paginator.page(page_num + 2) \
199                             if page_num + 1 < paginator.num_pages else None
200                     paginated_localcontext.update(
201                             {'%s_paginator' % key: paginator,
202                              '%s_page' % key: page,
203                              '%s_previous_page' % key: previous_page,
204                              '%s_next_page' % key: next_page})
205 
206                 _write_file(template, paginated_localcontext, self.output_path,
207                             page.save_as, override_output)
208         else:
209             # no pagination
210             _write_file(template, localcontext, self.output_path, name,
211                         override_output)
212
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pelican/writers.py b/pelican/writers.py
--- a/pelican/writers.py
+++ b/pelican/writers.py
@@ -8,6 +8,9 @@
 
 if not six.PY3:
     from codecs import open
+    from urlparse import urlparse
+else:
+    from urllib.parse import urlparse
 
 from feedgenerator import Atom1Feed, Rss201rev2Feed
 from jinja2 import Markup
@@ -41,11 +44,13 @@
     def _add_item_to_the_feed(self, feed, item):
 
         title = Markup(item.title).striptags()
+        link = '%s/%s' % (self.site_url, item.url)
         feed.add_item(
             title=title,
-            link='%s/%s' % (self.site_url, item.url),
-            unique_id='tag:%s,%s:%s' % (self.site_url.replace('http://', ''),
-                                        item.date.date(), item.url),
+            link=link,
+            unique_id='tag:%s,%s:%s' % (urlparse(link).netloc,
+                                        item.date.date(),
+                                        urlparse(link).path.lstrip('/')),
             description=item.get_content(self.site_url),
             categories=item.tags if hasattr(item, 'tags') else None,
             author_name=getattr(item, 'author', ''),

{"golden_diff": "diff --git a/pelican/writers.py b/pelican/writers.py\n--- a/pelican/writers.py\n+++ b/pelican/writers.py\n@@ -8,6 +8,9 @@\n \n if not six.PY3:\n     from codecs import open\n+    from urlparse import urlparse\n+else:\n+    from urllib.parse import urlparse\n \n from feedgenerator import Atom1Feed, Rss201rev2Feed\n from jinja2 import Markup\n@@ -41,11 +44,13 @@\n     def _add_item_to_the_feed(self, feed, item):\n \n         title = Markup(item.title).striptags()\n+        link = '%s/%s' % (self.site_url, item.url)\n         feed.add_item(\n             title=title,\n-            link='%s/%s' % (self.site_url, item.url),\n-            unique_id='tag:%s,%s:%s' % (self.site_url.replace('http://', ''),\n-                                        item.date.date(), item.url),\n+            link=link,\n+            unique_id='tag:%s,%s:%s' % (urlparse(link).netloc,\n+                                        item.date.date(),\n+                                        urlparse(link).path.lstrip('/')),\n             description=item.get_content(self.site_url),\n             categories=item.tags if hasattr(item, 'tags') else None,\n             author_name=getattr(item, 'author', ''),\n", "issue": "Atom feeds don't validate with SITEURL containing HTTPS scheme and/or a specific service port.\nWhen SITEURL = 'https://example.com' or 'http://example.com:8080', `writers.py` generates `unique_id` producing wrong 'TAG:' IDs.\n\nA possible fix could be to switch **line 45** from :\n\n``` python\nunique_id='tag:%s,%s:%s' % (self.site_url.replace('http://', ''),\n                            item.date.date(), item.url),\n```\n\nto :\n\n``` python\nunique_id='tag:%s,%s:%s' % (re.sub('^https?://(?P<host>.*?)(:\\d+)?$','\\g<host>',self.site_url),\n                            item.date.date(), item.url),\n```\n\nAtom feeds don't validate with SITEURL containing HTTPS scheme and/or a specific service port.\nWhen SITEURL = 'https://example.com' or 'http://example.com:8080', `writers.py` generates `unique_id` producing wrong 'TAG:' IDs.\n\nA possible fix could be to switch **line 45** from :\n\n``` python\nunique_id='tag:%s,%s:%s' % (self.site_url.replace('http://', ''),\n                            item.date.date(), item.url),\n```\n\nto :\n\n``` python\nunique_id='tag:%s,%s:%s' % (re.sub('^https?://(?P<host>.*?)(:\\d+)?$','\\g<host>',self.site_url),\n                            item.date.date(), item.url),\n```\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\nfrom __future__ import with_statement, unicode_literals, print_function\nimport six\n\nimport os\nimport locale\nimport logging\n\nif not six.PY3:\n    from codecs import open\n\nfrom feedgenerator import Atom1Feed, Rss201rev2Feed\nfrom jinja2 import Markup\n\nfrom pelican.paginator import Paginator\nfrom pelican.utils import get_relative_path, path_to_url, set_date_tzinfo\nfrom pelican import signals\n\nlogger = logging.getLogger(__name__)\n\n\nclass Writer(object):\n\n    def __init__(self, output_path, settings=None):\n        self.output_path = output_path\n        self.reminder = dict()\n        self.settings = settings or {}\n        self._written_files = set()\n        self._overridden_files = set()\n\n    def _create_new_feed(self, feed_type, context):\n        feed_class = Rss201rev2Feed if feed_type == 'rss' else Atom1Feed\n        sitename = Markup(context['SITENAME']).striptags()\n        feed = feed_class(\n            title=sitename,\n            link=(self.site_url + '/'),\n            feed_url=self.feed_url,\n            description=context.get('SITESUBTITLE', ''))\n        return feed\n\n    def _add_item_to_the_feed(self, feed, item):\n\n        title = Markup(item.title).striptags()\n        feed.add_item(\n            title=title,\n            link='%s/%s' % (self.site_url, item.url),\n            unique_id='tag:%s,%s:%s' % (self.site_url.replace('http://', ''),\n                                        item.date.date(), item.url),\n            description=item.get_content(self.site_url),\n            categories=item.tags if hasattr(item, 'tags') else None,\n            author_name=getattr(item, 'author', ''),\n            pubdate=set_date_tzinfo(item.date,\n                self.settings.get('TIMEZONE', None)))\n\n    def _open_w(self, filename, encoding, override=False):\n        \"\"\"Open a file to write some content to it.\n\n        Exit if we have already written to that file, unless one (and no more\n        than one) of the writes has the override parameter set to True.\n        \"\"\"\n        if filename in self._overridden_files:\n            if override:\n                raise RuntimeError('File %s is set to be overridden twice'\n                                    % filename)\n            else:\n                logger.info('skipping %s' % filename)\n                filename = os.devnull\n        elif filename in self._written_files:\n            if override:\n                logger.info('overwriting %s' % filename)\n            else:\n                raise RuntimeError('File %s is to be overwritten' % filename)\n        if override:\n            self._overridden_files.add(filename)\n        self._written_files.add(filename)\n        return open(filename, 'w', encoding=encoding)\n\n    def write_feed(self, elements, context, path=None, feed_type='atom'):\n        \"\"\"Generate a feed with the list of articles provided\n\n        Return the feed. If no path or output_path is specified, just\n        return the feed object.\n\n        :param elements: the articles to put on the feed.\n        :param context: the context to get the feed metadata.\n        :param path: the path to output.\n        :param feed_type: the feed type to use (atom or rss)\n        \"\"\"\n        old_locale = locale.setlocale(locale.LC_ALL)\n        locale.setlocale(locale.LC_ALL, str('C'))\n        try:\n            self.site_url = context.get(\n                'SITEURL', path_to_url(get_relative_path(path)))\n\n            self.feed_domain = context.get('FEED_DOMAIN')\n            self.feed_url = '{}/{}'.format(self.feed_domain, path)\n\n            feed = self._create_new_feed(feed_type, context)\n\n            max_items = len(elements)\n            if self.settings['FEED_MAX_ITEMS']:\n                max_items = min(self.settings['FEED_MAX_ITEMS'], max_items)\n            for i in range(max_items):\n                self._add_item_to_the_feed(feed, elements[i])\n\n            if path:\n                complete_path = os.path.join(self.output_path, path)\n                try:\n                    os.makedirs(os.path.dirname(complete_path))\n                except Exception:\n                    pass\n\n                encoding = 'utf-8' if six.PY3 else None\n                with self._open_w(complete_path, encoding) as fp:\n                    feed.write(fp, 'utf-8')\n                    logger.info('writing %s' % complete_path)\n            return feed\n        finally:\n            locale.setlocale(locale.LC_ALL, old_locale)\n\n    def write_file(self, name, template, context, relative_urls=False,\n        paginated=None, override_output=False, **kwargs):\n        \"\"\"Render the template and write the file.\n\n        :param name: name of the file to output\n        :param template: template to use to generate the content\n        :param context: dict to pass to the templates.\n        :param relative_urls: use relative urls or absolutes ones\n        :param paginated: dict of article list to paginate - must have the\n            same length (same list in different orders)\n        :param override_output: boolean telling if we can override previous\n            output with the same name (and if next files written with the same\n            name should be skipped to keep that one)\n        :param **kwargs: additional variables to pass to the templates\n        \"\"\"\n\n        if name is False:\n            return\n        elif not name:\n            # other stuff, just return for now\n            return\n\n        def _write_file(template, localcontext, output_path, name, override):\n            \"\"\"Render the template write the file.\"\"\"\n            old_locale = locale.setlocale(locale.LC_ALL)\n            locale.setlocale(locale.LC_ALL, str('C'))\n            try:\n                output = template.render(localcontext)\n            finally:\n                locale.setlocale(locale.LC_ALL, old_locale)\n            path = os.path.join(output_path, name)\n            try:\n                os.makedirs(os.path.dirname(path))\n            except Exception:\n                pass\n\n            with self._open_w(path, 'utf-8', override=override) as f:\n                f.write(output)\n            logger.info('writing {}'.format(path))\n\n            # Send a signal to say we're writing a file with some specific\n            # local context.\n            signals.content_written.send(path, context=localcontext)\n\n        localcontext = context.copy()\n        if relative_urls:\n            relative_url = path_to_url(get_relative_path(name))\n            context['localsiteurl'] = relative_url\n            localcontext['SITEURL'] = relative_url\n\n        localcontext['output_file'] = name\n        localcontext.update(kwargs)\n\n        # check paginated\n        paginated = paginated or {}\n        if paginated:\n            name_root = os.path.splitext(name)[0]\n\n            # pagination needed, init paginators\n            paginators = {}\n            for key in paginated.keys():\n                object_list = paginated[key]\n\n                paginators[key] = Paginator(\n                    name_root,\n                    object_list,\n                    self.settings,\n                )\n\n            # generated pages, and write\n            for page_num in range(list(paginators.values())[0].num_pages):\n                paginated_localcontext = localcontext.copy()\n                for key in paginators.keys():\n                    paginator = paginators[key]\n                    previous_page = paginator.page(page_num) \\\n                            if page_num > 0 else None\n                    page = paginator.page(page_num + 1)\n                    next_page = paginator.page(page_num + 2) \\\n                            if page_num + 1 < paginator.num_pages else None\n                    paginated_localcontext.update(\n                            {'%s_paginator' % key: paginator,\n                             '%s_page' % key: page,\n                             '%s_previous_page' % key: previous_page,\n                             '%s_next_page' % key: next_page})\n\n                _write_file(template, paginated_localcontext, self.output_path,\n                            page.save_as, override_output)\n        else:\n            # no pagination\n            _write_file(template, localcontext, self.output_path, name,\n                        override_output)\n", "path": "pelican/writers.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\nfrom __future__ import with_statement, unicode_literals, print_function\nimport six\n\nimport os\nimport locale\nimport logging\n\nif not six.PY3:\n    from codecs import open\n    from urlparse import urlparse\nelse:\n    from urllib.parse import urlparse\n\nfrom feedgenerator import Atom1Feed, Rss201rev2Feed\nfrom jinja2 import Markup\n\nfrom pelican.paginator import Paginator\nfrom pelican.utils import get_relative_path, path_to_url, set_date_tzinfo\nfrom pelican import signals\n\nlogger = logging.getLogger(__name__)\n\n\nclass Writer(object):\n\n    def __init__(self, output_path, settings=None):\n        self.output_path = output_path\n        self.reminder = dict()\n        self.settings = settings or {}\n        self._written_files = set()\n        self._overridden_files = set()\n\n    def _create_new_feed(self, feed_type, context):\n        feed_class = Rss201rev2Feed if feed_type == 'rss' else Atom1Feed\n        sitename = Markup(context['SITENAME']).striptags()\n        feed = feed_class(\n            title=sitename,\n            link=(self.site_url + '/'),\n            feed_url=self.feed_url,\n            description=context.get('SITESUBTITLE', ''))\n        return feed\n\n    def _add_item_to_the_feed(self, feed, item):\n\n        title = Markup(item.title).striptags()\n        link = '%s/%s' % (self.site_url, item.url)\n        feed.add_item(\n            title=title,\n            link=link,\n            unique_id='tag:%s,%s:%s' % (urlparse(link).netloc,\n                                        item.date.date(),\n                                        urlparse(link).path.lstrip('/')),\n            description=item.get_content(self.site_url),\n            categories=item.tags if hasattr(item, 'tags') else None,\n            author_name=getattr(item, 'author', ''),\n            pubdate=set_date_tzinfo(item.date,\n                self.settings.get('TIMEZONE', None)))\n\n    def _open_w(self, filename, encoding, override=False):\n        \"\"\"Open a file to write some content to it.\n\n        Exit if we have already written to that file, unless one (and no more\n        than one) of the writes has the override parameter set to True.\n        \"\"\"\n        if filename in self._overridden_files:\n            if override:\n                raise RuntimeError('File %s is set to be overridden twice'\n                                    % filename)\n            else:\n                logger.info('skipping %s' % filename)\n                filename = os.devnull\n        elif filename in self._written_files:\n            if override:\n                logger.info('overwriting %s' % filename)\n            else:\n                raise RuntimeError('File %s is to be overwritten' % filename)\n        if override:\n            self._overridden_files.add(filename)\n        self._written_files.add(filename)\n        return open(filename, 'w', encoding=encoding)\n\n    def write_feed(self, elements, context, path=None, feed_type='atom'):\n        \"\"\"Generate a feed with the list of articles provided\n\n        Return the feed. If no path or output_path is specified, just\n        return the feed object.\n\n        :param elements: the articles to put on the feed.\n        :param context: the context to get the feed metadata.\n        :param path: the path to output.\n        :param feed_type: the feed type to use (atom or rss)\n        \"\"\"\n        old_locale = locale.setlocale(locale.LC_ALL)\n        locale.setlocale(locale.LC_ALL, str('C'))\n        try:\n            self.site_url = context.get(\n                'SITEURL', path_to_url(get_relative_path(path)))\n\n            self.feed_domain = context.get('FEED_DOMAIN')\n            self.feed_url = '{}/{}'.format(self.feed_domain, path)\n\n            feed = self._create_new_feed(feed_type, context)\n\n            max_items = len(elements)\n            if self.settings['FEED_MAX_ITEMS']:\n                max_items = min(self.settings['FEED_MAX_ITEMS'], max_items)\n            for i in range(max_items):\n                self._add_item_to_the_feed(feed, elements[i])\n\n            if path:\n                complete_path = os.path.join(self.output_path, path)\n                try:\n                    os.makedirs(os.path.dirname(complete_path))\n                except Exception:\n                    pass\n\n                encoding = 'utf-8' if six.PY3 else None\n                with self._open_w(complete_path, encoding) as fp:\n                    feed.write(fp, 'utf-8')\n                    logger.info('writing %s' % complete_path)\n            return feed\n        finally:\n            locale.setlocale(locale.LC_ALL, old_locale)\n\n    def write_file(self, name, template, context, relative_urls=False,\n        paginated=None, override_output=False, **kwargs):\n        \"\"\"Render the template and write the file.\n\n        :param name: name of the file to output\n        :param template: template to use to generate the content\n        :param context: dict to pass to the templates.\n        :param relative_urls: use relative urls or absolutes ones\n        :param paginated: dict of article list to paginate - must have the\n            same length (same list in different orders)\n        :param override_output: boolean telling if we can override previous\n            output with the same name (and if next files written with the same\n            name should be skipped to keep that one)\n        :param **kwargs: additional variables to pass to the templates\n        \"\"\"\n\n        if name is False:\n            return\n        elif not name:\n            # other stuff, just return for now\n            return\n\n        def _write_file(template, localcontext, output_path, name, override):\n            \"\"\"Render the template write the file.\"\"\"\n            old_locale = locale.setlocale(locale.LC_ALL)\n            locale.setlocale(locale.LC_ALL, str('C'))\n            try:\n                output = template.render(localcontext)\n            finally:\n                locale.setlocale(locale.LC_ALL, old_locale)\n            path = os.path.join(output_path, name)\n            try:\n                os.makedirs(os.path.dirname(path))\n            except Exception:\n                pass\n\n            with self._open_w(path, 'utf-8', override=override) as f:\n                f.write(output)\n            logger.info('writing {}'.format(path))\n\n            # Send a signal to say we're writing a file with some specific\n            # local context.\n            signals.content_written.send(path, context=localcontext)\n\n        localcontext = context.copy()\n        if relative_urls:\n            relative_url = path_to_url(get_relative_path(name))\n            context['localsiteurl'] = relative_url\n            localcontext['SITEURL'] = relative_url\n\n        localcontext['output_file'] = name\n        localcontext.update(kwargs)\n\n        # check paginated\n        paginated = paginated or {}\n        if paginated:\n            name_root = os.path.splitext(name)[0]\n\n            # pagination needed, init paginators\n            paginators = {}\n            for key in paginated.keys():\n                object_list = paginated[key]\n\n                paginators[key] = Paginator(\n                    name_root,\n                    object_list,\n                    self.settings,\n                )\n\n            # generated pages, and write\n            for page_num in range(list(paginators.values())[0].num_pages):\n                paginated_localcontext = localcontext.copy()\n                for key in paginators.keys():\n                    paginator = paginators[key]\n                    previous_page = paginator.page(page_num) \\\n                            if page_num > 0 else None\n                    page = paginator.page(page_num + 1)\n                    next_page = paginator.page(page_num + 2) \\\n                            if page_num + 1 < paginator.num_pages else None\n                    paginated_localcontext.update(\n                            {'%s_paginator' % key: paginator,\n                             '%s_page' % key: page,\n                             '%s_previous_page' % key: previous_page,\n                             '%s_next_page' % key: next_page})\n\n                _write_file(template, paginated_localcontext, self.output_path,\n                            page.save_as, override_output)\n        else:\n            # no pagination\n            _write_file(template, localcontext, self.output_path, name,\n                        override_output)\n", "path": "pelican/writers.py"}]}