We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Site title entered in the @@plone-addsite form is not set as site title
Plone site title is set in the @@site-controlpanel form and saved in the registry. But the @@plone-addsite form gets the site title from the user and saves it as a Zope property in the portal object.


Related to https://github.com/plone/plone.app.layout/issues/317

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `Products/CMFPlone/factory.py`
Content:
```
1 from logging import getLogger
2 from plone.registry.interfaces import IRegistry
3 from Products.CMFPlone import PloneMessageFactory as _
4 from Products.CMFPlone.events import SiteManagerCreatedEvent
5 from plone.base.interfaces import INonInstallable
6 from Products.CMFPlone.Portal import PloneSite
7 from Products.GenericSetup.tool import SetupTool
8 from zope.component import queryUtility
9 from zope.component.hooks import setSite
10 from zope.event import notify
11 from zope.interface import implementer
12 from zope.lifecycleevent import ObjectCreatedEvent
13 
14 _TOOL_ID = 'portal_setup'
15 _DEFAULT_PROFILE = 'Products.CMFPlone:plone'
16 _TYPES_PROFILE = 'plone.app.contenttypes:default'
17 _CONTENT_PROFILE = 'plone.app.contenttypes:plone-content'
18 
19 # A little hint for PloneTestCase (pre-Plone 6.0)
20 _IMREALLYPLONE5 = True
21 
22 # Marker hints for code that needs to know the major Plone version
23 # Works the same way than zcml condition hints so it contains the current and the
24 # last ones
25 PLONE52MARKER = True
26 PLONE60MARKER = True
27 
28 logger = getLogger('Plone')
29 
30 
31 @implementer(INonInstallable)
32 class NonInstallable:
33 
34     def getNonInstallableProducts(self):
35         return [
36             'CMFDefault', 'Products.CMFDefault',
37             'CMFPlone', 'Products.CMFPlone', 'Products.CMFPlone.migrations',
38             'CMFTopic', 'Products.CMFTopic',
39             'CMFUid', 'Products.CMFUid',
40             'DCWorkflow', 'Products.DCWorkflow',
41             'PasswordResetTool', 'Products.PasswordResetTool',
42             'PlonePAS', 'Products.PlonePAS',
43             'PloneLanguageTool', 'Products.PloneLanguageTool',
44             'MimetypesRegistry', 'Products.MimetypesRegistry',
45             'PortalTransforms', 'Products.PortalTransforms',
46             'CMFDiffTool', 'Products.CMFDiffTool',
47             'CMFEditions', 'Products.CMFEditions',
48             'Products.NuPlone',
49             'borg.localrole',
50             'plone.app.caching',
51             'plone.app.dexterity',
52             'plone.app.discussion',
53             'plone.app.event',
54             'plone.app.intid',
55             'plone.app.linkintegrity',
56             'plone.app.querystring',
57             'plone.app.registry',
58             'plone.app.referenceablebehavior',
59             'plone.app.relationfield',
60             'plone.app.theming',
61             'plone.app.users',
62             'plone.app.widgets',
63             'plone.app.z3cform',
64             'plone.formwidget.recurrence',
65             'plone.keyring',
66             'plone.outputfilters',
67             'plone.portlet.static',
68             'plone.portlet.collection',
69             'plone.protect',
70             'plone.resource',
71             'plonetheme.barceloneta',
72         ]
73 
74     def getNonInstallableProfiles(self):
75         return [_DEFAULT_PROFILE,
76                 _CONTENT_PROFILE,
77                 'Products.CMFDiffTool:CMFDiffTool',
78                 'Products.CMFEditions:CMFEditions',
79                 'Products.CMFPlone:dependencies',
80                 'Products.CMFPlone:testfixture',
81                 'Products.NuPlone:uninstall',
82                 'Products.MimetypesRegistry:MimetypesRegistry',
83                 'Products.PasswordResetTool:PasswordResetTool',
84                 'Products.PortalTransforms:PortalTransforms',
85                 'Products.PloneLanguageTool:PloneLanguageTool',
86                 'Products.PlonePAS:PlonePAS',
87                 'borg.localrole:default',
88                 'plone.browserlayer:default',
89                 'plone.keyring:default',
90                 'plone.outputfilters:default',
91                 'plone.portlet.static:default',
92                 'plone.portlet.collection:default',
93                 'plone.protect:default',
94                 'plone.app.contenttypes:default',
95                 'plone.app.dexterity:default',
96                 'plone.app.discussion:default',
97                 'plone.app.event:default',
98                 'plone.app.linkintegrity:default',
99                 'plone.app.registry:default',
100                 'plone.app.relationfield:default',
101                 'plone.app.theming:default',
102                 'plone.app.users:default',
103                 'plone.app.versioningbehavior:default',
104                 'plone.app.z3cform:default',
105                 'plone.formwidget.recurrence:default',
106                 'plone.resource:default',
107                 ]
108 
109 
110 def zmi_constructor(context):
111     """This is a dummy constructor for the ZMI."""
112     url = context.DestinationURL()
113     request = context.REQUEST
114     return request.response.redirect(url + '/@@plone-addsite?site_id=Plone')
115 
116 
117 def addPloneSite(context, site_id, title='Plone site', description='',
118                  profile_id=_DEFAULT_PROFILE,
119                  content_profile_id=_CONTENT_PROFILE, snapshot=False,
120                  extension_ids=(), setup_content=True,
121                  default_language='en', portal_timezone='UTC'):
122     """Add a PloneSite to the context."""
123 
124     site = PloneSite(site_id)
125     notify(ObjectCreatedEvent(site))
126     context[site_id] = site
127 
128     site = context[site_id]
129     site.setLanguage(default_language)
130     # Set the accepted language for the rest of the request.  This makes sure
131     # the front-page text gets the correct translation also when your browser
132     # prefers non-English and you choose English as language for the Plone
133     # Site.
134     request = context.REQUEST
135     request['HTTP_ACCEPT_LANGUAGE'] = default_language
136 
137     site[_TOOL_ID] = SetupTool(_TOOL_ID)
138     setup_tool = site[_TOOL_ID]
139 
140     notify(SiteManagerCreatedEvent(site))
141     setSite(site)
142 
143     try:
144         setup_tool.setBaselineContext('profile-%s' % profile_id)
145         setup_tool.runAllImportStepsFromProfile('profile-%s' % profile_id)
146 
147         reg = queryUtility(IRegistry, context=site)
148         reg['plone.portal_timezone'] = portal_timezone
149         reg['plone.available_timezones'] = [portal_timezone]
150         reg['plone.default_language'] = default_language
151         reg['plone.available_languages'] = [default_language]
152 
153         # Install default content types profile if user do not select "example content"
154         # during site creation.
155         content_types_profile = content_profile_id if setup_content else _TYPES_PROFILE
156 
157         setup_tool.runAllImportStepsFromProfile(f'profile-{content_types_profile}')
158 
159         props = dict(
160             title=title,
161             description=description,
162         )
163         # Do this before applying extension profiles, so the settings from a
164         # properties.xml file are applied and not overwritten by this
165         site.manage_changeProperties(**props)
166 
167         for extension_id in extension_ids:
168             try:
169                 setup_tool.runAllImportStepsFromProfile(f"profile-{extension_id}")
170             except Exception:
171                 logger.error(f"Error while installing profile {extension_id}:")
172                 raise
173 
174         if snapshot is True:
175             setup_tool.createSnapshot('initial_configuration')
176 
177         return site
178     except Exception:
179         setSite(None)
180         raise
181
```
--- 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/Products/CMFPlone/factory.py b/Products/CMFPlone/factory.py
--- a/Products/CMFPlone/factory.py
+++ b/Products/CMFPlone/factory.py
@@ -149,6 +149,7 @@
         reg['plone.available_timezones'] = [portal_timezone]
         reg['plone.default_language'] = default_language
         reg['plone.available_languages'] = [default_language]
+        reg['plone.site_title'] = title
 
         # Install default content types profile if user do not select "example content"
         # during site creation.

{"golden_diff": "diff --git a/Products/CMFPlone/factory.py b/Products/CMFPlone/factory.py\n--- a/Products/CMFPlone/factory.py\n+++ b/Products/CMFPlone/factory.py\n@@ -149,6 +149,7 @@\n         reg['plone.available_timezones'] = [portal_timezone]\n         reg['plone.default_language'] = default_language\n         reg['plone.available_languages'] = [default_language]\n+        reg['plone.site_title'] = title\n \n         # Install default content types profile if user do not select \"example content\"\n         # during site creation.\n", "issue": "Site title entered in the @@plone-addsite form is not set as site title\nPlone site title is set in the @@site-controlpanel form and saved in the registry. But the @@plone-addsite form gets the site title from the user and saves it as a Zope property in the portal object.\r\n\r\n\r\nRelated to https://github.com/plone/plone.app.layout/issues/317\n", "before_files": [{"content": "from logging import getLogger\nfrom plone.registry.interfaces import IRegistry\nfrom Products.CMFPlone import PloneMessageFactory as _\nfrom Products.CMFPlone.events import SiteManagerCreatedEvent\nfrom plone.base.interfaces import INonInstallable\nfrom Products.CMFPlone.Portal import PloneSite\nfrom Products.GenericSetup.tool import SetupTool\nfrom zope.component import queryUtility\nfrom zope.component.hooks import setSite\nfrom zope.event import notify\nfrom zope.interface import implementer\nfrom zope.lifecycleevent import ObjectCreatedEvent\n\n_TOOL_ID = 'portal_setup'\n_DEFAULT_PROFILE = 'Products.CMFPlone:plone'\n_TYPES_PROFILE = 'plone.app.contenttypes:default'\n_CONTENT_PROFILE = 'plone.app.contenttypes:plone-content'\n\n# A little hint for PloneTestCase (pre-Plone 6.0)\n_IMREALLYPLONE5 = True\n\n# Marker hints for code that needs to know the major Plone version\n# Works the same way than zcml condition hints so it contains the current and the\n# last ones\nPLONE52MARKER = True\nPLONE60MARKER = True\n\nlogger = getLogger('Plone')\n\n\n@implementer(INonInstallable)\nclass NonInstallable:\n\n    def getNonInstallableProducts(self):\n        return [\n            'CMFDefault', 'Products.CMFDefault',\n            'CMFPlone', 'Products.CMFPlone', 'Products.CMFPlone.migrations',\n            'CMFTopic', 'Products.CMFTopic',\n            'CMFUid', 'Products.CMFUid',\n            'DCWorkflow', 'Products.DCWorkflow',\n            'PasswordResetTool', 'Products.PasswordResetTool',\n            'PlonePAS', 'Products.PlonePAS',\n            'PloneLanguageTool', 'Products.PloneLanguageTool',\n            'MimetypesRegistry', 'Products.MimetypesRegistry',\n            'PortalTransforms', 'Products.PortalTransforms',\n            'CMFDiffTool', 'Products.CMFDiffTool',\n            'CMFEditions', 'Products.CMFEditions',\n            'Products.NuPlone',\n            'borg.localrole',\n            'plone.app.caching',\n            'plone.app.dexterity',\n            'plone.app.discussion',\n            'plone.app.event',\n            'plone.app.intid',\n            'plone.app.linkintegrity',\n            'plone.app.querystring',\n            'plone.app.registry',\n            'plone.app.referenceablebehavior',\n            'plone.app.relationfield',\n            'plone.app.theming',\n            'plone.app.users',\n            'plone.app.widgets',\n            'plone.app.z3cform',\n            'plone.formwidget.recurrence',\n            'plone.keyring',\n            'plone.outputfilters',\n            'plone.portlet.static',\n            'plone.portlet.collection',\n            'plone.protect',\n            'plone.resource',\n            'plonetheme.barceloneta',\n        ]\n\n    def getNonInstallableProfiles(self):\n        return [_DEFAULT_PROFILE,\n                _CONTENT_PROFILE,\n                'Products.CMFDiffTool:CMFDiffTool',\n                'Products.CMFEditions:CMFEditions',\n                'Products.CMFPlone:dependencies',\n                'Products.CMFPlone:testfixture',\n                'Products.NuPlone:uninstall',\n                'Products.MimetypesRegistry:MimetypesRegistry',\n                'Products.PasswordResetTool:PasswordResetTool',\n                'Products.PortalTransforms:PortalTransforms',\n                'Products.PloneLanguageTool:PloneLanguageTool',\n                'Products.PlonePAS:PlonePAS',\n                'borg.localrole:default',\n                'plone.browserlayer:default',\n                'plone.keyring:default',\n                'plone.outputfilters:default',\n                'plone.portlet.static:default',\n                'plone.portlet.collection:default',\n                'plone.protect:default',\n                'plone.app.contenttypes:default',\n                'plone.app.dexterity:default',\n                'plone.app.discussion:default',\n                'plone.app.event:default',\n                'plone.app.linkintegrity:default',\n                'plone.app.registry:default',\n                'plone.app.relationfield:default',\n                'plone.app.theming:default',\n                'plone.app.users:default',\n                'plone.app.versioningbehavior:default',\n                'plone.app.z3cform:default',\n                'plone.formwidget.recurrence:default',\n                'plone.resource:default',\n                ]\n\n\ndef zmi_constructor(context):\n    \"\"\"This is a dummy constructor for the ZMI.\"\"\"\n    url = context.DestinationURL()\n    request = context.REQUEST\n    return request.response.redirect(url + '/@@plone-addsite?site_id=Plone')\n\n\ndef addPloneSite(context, site_id, title='Plone site', description='',\n                 profile_id=_DEFAULT_PROFILE,\n                 content_profile_id=_CONTENT_PROFILE, snapshot=False,\n                 extension_ids=(), setup_content=True,\n                 default_language='en', portal_timezone='UTC'):\n    \"\"\"Add a PloneSite to the context.\"\"\"\n\n    site = PloneSite(site_id)\n    notify(ObjectCreatedEvent(site))\n    context[site_id] = site\n\n    site = context[site_id]\n    site.setLanguage(default_language)\n    # Set the accepted language for the rest of the request.  This makes sure\n    # the front-page text gets the correct translation also when your browser\n    # prefers non-English and you choose English as language for the Plone\n    # Site.\n    request = context.REQUEST\n    request['HTTP_ACCEPT_LANGUAGE'] = default_language\n\n    site[_TOOL_ID] = SetupTool(_TOOL_ID)\n    setup_tool = site[_TOOL_ID]\n\n    notify(SiteManagerCreatedEvent(site))\n    setSite(site)\n\n    try:\n        setup_tool.setBaselineContext('profile-%s' % profile_id)\n        setup_tool.runAllImportStepsFromProfile('profile-%s' % profile_id)\n\n        reg = queryUtility(IRegistry, context=site)\n        reg['plone.portal_timezone'] = portal_timezone\n        reg['plone.available_timezones'] = [portal_timezone]\n        reg['plone.default_language'] = default_language\n        reg['plone.available_languages'] = [default_language]\n\n        # Install default content types profile if user do not select \"example content\"\n        # during site creation.\n        content_types_profile = content_profile_id if setup_content else _TYPES_PROFILE\n\n        setup_tool.runAllImportStepsFromProfile(f'profile-{content_types_profile}')\n\n        props = dict(\n            title=title,\n            description=description,\n        )\n        # Do this before applying extension profiles, so the settings from a\n        # properties.xml file are applied and not overwritten by this\n        site.manage_changeProperties(**props)\n\n        for extension_id in extension_ids:\n            try:\n                setup_tool.runAllImportStepsFromProfile(f\"profile-{extension_id}\")\n            except Exception:\n                logger.error(f\"Error while installing profile {extension_id}:\")\n                raise\n\n        if snapshot is True:\n            setup_tool.createSnapshot('initial_configuration')\n\n        return site\n    except Exception:\n        setSite(None)\n        raise\n", "path": "Products/CMFPlone/factory.py"}], "after_files": [{"content": "from logging import getLogger\nfrom plone.registry.interfaces import IRegistry\nfrom Products.CMFPlone import PloneMessageFactory as _\nfrom Products.CMFPlone.events import SiteManagerCreatedEvent\nfrom plone.base.interfaces import INonInstallable\nfrom Products.CMFPlone.Portal import PloneSite\nfrom Products.GenericSetup.tool import SetupTool\nfrom zope.component import queryUtility\nfrom zope.component.hooks import setSite\nfrom zope.event import notify\nfrom zope.interface import implementer\nfrom zope.lifecycleevent import ObjectCreatedEvent\n\n_TOOL_ID = 'portal_setup'\n_DEFAULT_PROFILE = 'Products.CMFPlone:plone'\n_TYPES_PROFILE = 'plone.app.contenttypes:default'\n_CONTENT_PROFILE = 'plone.app.contenttypes:plone-content'\n\n# A little hint for PloneTestCase (pre-Plone 6.0)\n_IMREALLYPLONE5 = True\n\n# Marker hints for code that needs to know the major Plone version\n# Works the same way than zcml condition hints so it contains the current and the\n# last ones\nPLONE52MARKER = True\nPLONE60MARKER = True\n\nlogger = getLogger('Plone')\n\n\n@implementer(INonInstallable)\nclass NonInstallable:\n\n    def getNonInstallableProducts(self):\n        return [\n            'CMFDefault', 'Products.CMFDefault',\n            'CMFPlone', 'Products.CMFPlone', 'Products.CMFPlone.migrations',\n            'CMFTopic', 'Products.CMFTopic',\n            'CMFUid', 'Products.CMFUid',\n            'DCWorkflow', 'Products.DCWorkflow',\n            'PasswordResetTool', 'Products.PasswordResetTool',\n            'PlonePAS', 'Products.PlonePAS',\n            'PloneLanguageTool', 'Products.PloneLanguageTool',\n            'MimetypesRegistry', 'Products.MimetypesRegistry',\n            'PortalTransforms', 'Products.PortalTransforms',\n            'CMFDiffTool', 'Products.CMFDiffTool',\n            'CMFEditions', 'Products.CMFEditions',\n            'Products.NuPlone',\n            'borg.localrole',\n            'plone.app.caching',\n            'plone.app.dexterity',\n            'plone.app.discussion',\n            'plone.app.event',\n            'plone.app.intid',\n            'plone.app.linkintegrity',\n            'plone.app.querystring',\n            'plone.app.registry',\n            'plone.app.referenceablebehavior',\n            'plone.app.relationfield',\n            'plone.app.theming',\n            'plone.app.users',\n            'plone.app.widgets',\n            'plone.app.z3cform',\n            'plone.formwidget.recurrence',\n            'plone.keyring',\n            'plone.outputfilters',\n            'plone.portlet.static',\n            'plone.portlet.collection',\n            'plone.protect',\n            'plone.resource',\n            'plonetheme.barceloneta',\n        ]\n\n    def getNonInstallableProfiles(self):\n        return [_DEFAULT_PROFILE,\n                _CONTENT_PROFILE,\n                'Products.CMFDiffTool:CMFDiffTool',\n                'Products.CMFEditions:CMFEditions',\n                'Products.CMFPlone:dependencies',\n                'Products.CMFPlone:testfixture',\n                'Products.NuPlone:uninstall',\n                'Products.MimetypesRegistry:MimetypesRegistry',\n                'Products.PasswordResetTool:PasswordResetTool',\n                'Products.PortalTransforms:PortalTransforms',\n                'Products.PloneLanguageTool:PloneLanguageTool',\n                'Products.PlonePAS:PlonePAS',\n                'borg.localrole:default',\n                'plone.browserlayer:default',\n                'plone.keyring:default',\n                'plone.outputfilters:default',\n                'plone.portlet.static:default',\n                'plone.portlet.collection:default',\n                'plone.protect:default',\n                'plone.app.contenttypes:default',\n                'plone.app.dexterity:default',\n                'plone.app.discussion:default',\n                'plone.app.event:default',\n                'plone.app.linkintegrity:default',\n                'plone.app.registry:default',\n                'plone.app.relationfield:default',\n                'plone.app.theming:default',\n                'plone.app.users:default',\n                'plone.app.versioningbehavior:default',\n                'plone.app.z3cform:default',\n                'plone.formwidget.recurrence:default',\n                'plone.resource:default',\n                ]\n\n\ndef zmi_constructor(context):\n    \"\"\"This is a dummy constructor for the ZMI.\"\"\"\n    url = context.DestinationURL()\n    request = context.REQUEST\n    return request.response.redirect(url + '/@@plone-addsite?site_id=Plone')\n\n\ndef addPloneSite(context, site_id, title='Plone site', description='',\n                 profile_id=_DEFAULT_PROFILE,\n                 content_profile_id=_CONTENT_PROFILE, snapshot=False,\n                 extension_ids=(), setup_content=True,\n                 default_language='en', portal_timezone='UTC'):\n    \"\"\"Add a PloneSite to the context.\"\"\"\n\n    site = PloneSite(site_id)\n    notify(ObjectCreatedEvent(site))\n    context[site_id] = site\n\n    site = context[site_id]\n    site.setLanguage(default_language)\n    # Set the accepted language for the rest of the request.  This makes sure\n    # the front-page text gets the correct translation also when your browser\n    # prefers non-English and you choose English as language for the Plone\n    # Site.\n    request = context.REQUEST\n    request['HTTP_ACCEPT_LANGUAGE'] = default_language\n\n    site[_TOOL_ID] = SetupTool(_TOOL_ID)\n    setup_tool = site[_TOOL_ID]\n\n    notify(SiteManagerCreatedEvent(site))\n    setSite(site)\n\n    try:\n        setup_tool.setBaselineContext('profile-%s' % profile_id)\n        setup_tool.runAllImportStepsFromProfile('profile-%s' % profile_id)\n\n        reg = queryUtility(IRegistry, context=site)\n        reg['plone.portal_timezone'] = portal_timezone\n        reg['plone.available_timezones'] = [portal_timezone]\n        reg['plone.default_language'] = default_language\n        reg['plone.available_languages'] = [default_language]\n        reg['plone.site_title'] = title\n\n        # Install default content types profile if user do not select \"example content\"\n        # during site creation.\n        content_types_profile = content_profile_id if setup_content else _TYPES_PROFILE\n\n        setup_tool.runAllImportStepsFromProfile(f'profile-{content_types_profile}')\n\n        props = dict(\n            title=title,\n            description=description,\n        )\n        # Do this before applying extension profiles, so the settings from a\n        # properties.xml file are applied and not overwritten by this\n        site.manage_changeProperties(**props)\n\n        for extension_id in extension_ids:\n            try:\n                setup_tool.runAllImportStepsFromProfile(f\"profile-{extension_id}\")\n            except Exception:\n                logger.error(f\"Error while installing profile {extension_id}:\")\n                raise\n\n        if snapshot is True:\n            setup_tool.createSnapshot('initial_configuration')\n\n        return site\n    except Exception:\n        setSite(None)\n        raise\n", "path": "Products/CMFPlone/factory.py"}]}