diff --git a/bt5/erp5_discussion/SkinTemplateItem/portal_skins/erp5_discussion/WebSection_createBlogAndForum.py b/bt5/erp5_discussion/SkinTemplateItem/portal_skins/erp5_discussion/WebSection_createBlogAndForum.py
new file mode 100644
index 0000000000000000000000000000000000000000..87d6375dc1d988ac6a91a6ba2ff060fcf85bf7f7
--- /dev/null
+++ b/bt5/erp5_discussion/SkinTemplateItem/portal_skins/erp5_discussion/WebSection_createBlogAndForum.py
@@ -0,0 +1,62 @@
+if not create_blog and not create_forum:
+  return context.Base_redirect(
+    form_id,
+    keep_items = dict(portal_status_message = context.Base_translateString("Nothing to do."))
+  )
+
+membership_criterion_base_category_set = set(context.getMembershipCriterionBaseCategoryList())
+multimembership_criterion_base_category_set = set(context.getMultimembershipCriterionBaseCategoryList())
+
+multimembership_criterion_base_category_set.update(membership_criterion_base_category_set)
+multimembership_criterion_base_category_set.add("publication_section")
+
+membership_criterion_base_category_list = []
+multimembership_criterion_base_category_list = list(multimembership_criterion_base_category_set)
+membership_criterion_category_list = context.getMembershipCriterionCategoryList()
+
+info_list = []
+
+if create_blog:
+  # create blog
+  predicate = context.newContent(
+    portal_type = 'Web Section', 
+    id = blog_id,
+    title = "Blog",
+    visible = True,
+    default_page_displayed = True,
+    custom_render_method_id = "WebSection_viewBlogFrontPage",
+    criterion_property = ("portal_type",),
+    empty_criterion_valid = True,
+    membership_criterion_base_category = membership_criterion_base_category_list,
+    multimembership_criterion_base_category = multimembership_criterion_base_category_list,
+    membership_criterion_category = membership_criterion_category_list + ["publication_section/blog"],
+  )
+  predicate.setCriterion("portal_type", "Web Page")
+  info_list.append("blog")
+
+if create_forum:
+  # create forum
+  predicate = context.newContent(
+    portal_type = 'Web Section', 
+    id = forum_id,
+    title = "Forum",
+    visible = True,
+    default_page_displayed = True,
+    authorization_forced = 1,
+    custom_render_method_id = "WebSection_viewDiscussionThreadForm",
+    criterion_property = ("portal_type",),
+    empty_criterion_valid = True,
+    membership_criterion_base_category = membership_criterion_base_category_list,
+    multimembership_criterion_base_category = multimembership_criterion_base_category_list,
+    membership_criterion_category = membership_criterion_category_list + ["publication_section/forum"],
+  )
+  predicate.setCriterion("portal_type", "Discussion Thread")
+  info_list.append("forum")
+
+info_list = info_list[:-2] + [" and ".join(info_list[-2:])]
+info = ", ".join(info_list) + " created with default configuration."
+info = info[:1].upper() + info[1:]
+return context.Base_redirect(
+  form_id,
+  keep_items = dict(portal_status_message = context.Base_translateString(info))
+)
diff --git a/bt5/erp5_discussion/SkinTemplateItem/portal_skins/erp5_discussion/WebSection_createBlogAndForum.xml b/bt5/erp5_discussion/SkinTemplateItem/portal_skins/erp5_discussion/WebSection_createBlogAndForum.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b489faabb4f501cca5b6065801ca2181eafc62b6
--- /dev/null
+++ b/bt5/erp5_discussion/SkinTemplateItem/portal_skins/erp5_discussion/WebSection_createBlogAndForum.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="_reconstructor" module="copy_reg"/>
+                </klass>
+                <tuple>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                  <global name="object" module="__builtin__"/>
+                  <none/>
+                </tuple>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_container</string> </key>
+                                <value> <string>container</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_context</string> </key>
+                                <value> <string>context</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_m_self</string> </key>
+                                <value> <string>script</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>_params</string> </key>
+            <value> <string>create_blog=False, create_forum=False, blog_id="blog", forum_id="forum", form_id="view"</string> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>WebSection_createBlogAndForum</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_discussion/SkinTemplateItem/portal_skins/erp5_discussion/test_forum_creation.py b/bt5/erp5_discussion/SkinTemplateItem/portal_skins/erp5_discussion/test_forum_creation.py
new file mode 100644
index 0000000000000000000000000000000000000000..8fd86eef23b49e2beb5df858cc228c809bdbdb31
--- /dev/null
+++ b/bt5/erp5_discussion/SkinTemplateItem/portal_skins/erp5_discussion/test_forum_creation.py
@@ -0,0 +1,137 @@
+portal = context.getPortalObject()
+test_id = "roque_test"
+
+# utils functions -----------------------------------------------------------
+def _mixDict(*dict_list):
+  result = {}
+  for obj in dict_list:
+    result.update(obj)
+  return result
+def _createObject(from_, mixKW, searchKW={}, newContentKW={}):
+  result = from_.searchFolder(**_mixDict(mixKW, searchKW))
+  len_result = len(result)
+  if len_result == 0:
+    return from_.newContent(**_mixDict(mixKW, newContentKW))
+  if len_result == 1:
+    return result[0]
+  raise ValueError("Cannot choose object, check instance state")
+# // utils functions ---------------------------------------------------------
+
+# setup site -----------------------------------------------------------------
+try:
+  # - web_site_module/site_$id
+  test_web_site = _createObject(
+    portal.web_site_module,
+    dict(
+      portal_type = "Web Site",
+      id = test_id + "_web_site"
+    )
+  )
+  # - web_site_module/site_$id/public_websection
+  test_public_web_section = _createObject(
+    test_web_site,
+    dict(
+      portal_type = "Web Section",
+      id = "public_section"
+    )
+  )
+  # - portal_categories/publication_section/blog
+  publication_section_blog = _createObject(
+    portal.portal_categories.publication_section, dict(
+      portal_type = "Category",
+      id = "blog"
+    ), newContentKW = dict(title = "Blog")
+  )
+  publication_section_blog_path = "publication_section/blog"
+  # - portal_categories/publication_section/forum
+  publication_section_forum = _createObject(
+    portal.portal_categories.publication_section,
+    dict(
+      portal_type = "Category",
+      id = "forum"
+    ),
+    newContentKW = dict(title = "Forum")
+  )
+  publication_section_forum_path = "publication_section/forum"
+except:
+  pass
+# // setup site ---------------------------------------------------------------
+
+# create public blog and forum
+try:
+  test_public_web_section.WebSection_createBlogAndForum(
+    create_blog=True,
+    create_forum=True,
+    blog_id="blog_%s" % test_id,
+    forum_id="forum_%s" % test_id,
+  )
+except:
+  pass
+
+try:
+  # check what was created
+  blog = test_public_web_section.searchFolder(
+    portal_type="Web Section",
+    id="blog_%s" % test_id
+  )[0].getObject()
+  forum = test_public_web_section.searchFolder(
+    portal_type="Web Section",
+    id="forum_%s" % test_id
+  )[0].getObject()
+
+  print("!---- test created objects ----------------------------------------")
+  print("blog.getMembershipCriterionCategoryList (should be %s):" % publication_section_blog_path)
+  print(blog.getMembershipCriterionCategoryList())
+  print('blog criterion list (should be ("portal_type", "Web Page")):')
+  print([(x.property, x.identity) for x in blog.getCriterionList()])
+  print("forum.getMembershipCriterionCategoryList (should be %s):" % publication_section_forum_path)
+  print(forum.getMembershipCriterionCategoryList())
+  print('forum criterion list (should be ("portal_type", "Discussion Thread")):')
+  print([(x.property, x.identity) for x in forum.getCriterionList()])
+
+  print(blog.getRelativeUrl())
+  print(forum.getRelativeUrl())
+except IndexError:
+  print("re-run for tic()")
+
+# check objects created via UI
+try:
+  thread = portal.discussion_thread_module.searchFolder(
+    portal_type="Discussion Thread",
+    id=6
+  )[0].getObject()
+  post = thread.searchFolder(
+    portal_type="Discussion Post"
+  )[0].getObject()
+  print()
+  print("!---- objects created via UI ----------------------------------------")
+  print(thread.getRelativeUrl())
+  print(post.getRelativeUrl())
+  # test_public_web_section
+  membership_criterion_category_list = test_public_web_section.getMembershipCriterionCategoryList()
+  multimembership_criterion_base_category_list = test_public_web_section.getMultimembershipCriterionBaseCategoryList()
+  print()
+  print("!---- test web section categories ----------------------------------------")
+  print("membership_criterion_category_list")
+  print(membership_criterion_category_list)
+  print("multimembership_criterion_base_category_list")
+  print(multimembership_criterion_base_category_list)
+  membership_criterion_category_list = forum.getMembershipCriterionCategoryList()
+  multimembership_criterion_base_category_list = forum.getMultimembershipCriterionBaseCategoryList()
+  print()
+  print("!---- forum web section categories ----------------------------------------")
+  print("membership_criterion_category_list")
+  print(membership_criterion_category_list)
+  print("multimembership_criterion_base_category_list")
+  print(multimembership_criterion_base_category_list)
+  category_list = thread.getCategoryList()
+  print()
+  print("!---- thread and post categories ----------------------------------------")
+  print("thread category_list")
+  print(category_list)
+  category_list = post.getCategoryList()
+  print("post category_list")
+  print(category_list)
+except:
+  print("no objects created via UI")
+return printed
diff --git a/bt5/erp5_discussion/SkinTemplateItem/portal_skins/erp5_discussion/test_forum_creation.xml b/bt5/erp5_discussion/SkinTemplateItem/portal_skins/erp5_discussion/test_forum_creation.xml
new file mode 100644
index 0000000000000000000000000000000000000000..57c712f214e72a8bc555f6384c33af51f17ede18
--- /dev/null
+++ b/bt5/erp5_discussion/SkinTemplateItem/portal_skins/erp5_discussion/test_forum_creation.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="_reconstructor" module="copy_reg"/>
+                </klass>
+                <tuple>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                  <global name="object" module="__builtin__"/>
+                  <none/>
+                </tuple>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_container</string> </key>
+                                <value> <string>container</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_context</string> </key>
+                                <value> <string>context</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_m_self</string> </key>
+                                <value> <string>script</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>_params</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>test_forum_creation</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>