We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Tutorial form: Markdown for code does not work
See example tutorial
https://openenergy-platform.org/tutorials/12/

This would be important for our beginners tutorial to work:
https://openenergy-platform.org/tutorials/11/
 

> See also #405 





--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `tutorials/views.py`
Content:
```
1 from django.shortcuts import render, redirect
2 from django.views import View
3 from django.views.generic.edit import CreateView, UpdateView, DeleteView
4 from django.urls import exceptions, reverse_lazy
5 from django.contrib.auth.mixins import LoginRequiredMixin
6 
7 import os
8 import json
9 
10 from copy import deepcopy
11 
12 from django.conf import settings
13 
14 from markdown2 import Markdown
15 
16 from .forms import TutorialForm
17 from .models import Tutorial
18 
19 import re
20 # Create your views here.
21 
22 youtubeUrlRegex = re.compile('^.*youtube\.com\/watch\?v=(?P<id>[A-z0-9]+)$')
23 
24 def _resolveStaticTutorial(tutorial):
25     try:
26         with open(os.path.join(settings.BASE_DIR, "examples", "build", tutorial["fileName"]), 'r') as buildFile:
27                 buildFileContent = buildFile.read()
28 
29         return {
30             "html": buildFileContent
31         }
32 
33     except:
34         return {"html": "Tutorial is missing"}
35 
36 
37 def _resolveStaticTutorials():
38     resolvedTutorials = []
39 
40     # Load list of static tutorials
41 
42     try:
43         with open(os.path.join(settings.BASE_DIR, "examples", "build", 'meta.json'), 'r') as metaFile:
44             metaContent = json.load(metaFile)
45 
46             for tutorial in metaContent:
47                 rTut = _resolveStaticTutorial(tutorial)
48                 resolvedTutorials.append({
49                     'id': tutorial['id'],
50                     'fileName': tutorial['fileName'],
51                     'title': tutorial['title'] or tutorial['fileName'],
52                     'html': rTut['html'],
53                 })
54 
55             return sorted(resolvedTutorials, key=lambda x: x["title"])
56     except Exception as e:
57         print('Static tutorials could not be loaded, error=%s' % e)
58         # If we do not have a generated meta.json or we cannot read them, we just do not return any static
59         # tutorials. This is completly fine and dynamic tutorials can be used like normal.
60         return []
61 
62 
63 def _resolveDynamicTutorial(evaluatedQs):
64     """
65 
66 
67     :param evaluatedQs: Evaluated queryset object
68     :return:
69     """
70 
71     # Initialize dict that stores a tutorial
72     currentTutorial = {'id': '', 'title': '', 'html': '', 'markdown': '', 'category': '', 'media_src': '', 'level': ''}
73 
74     # populate dict
75     currentTutorial.update(id=str(evaluatedQs.id),
76                            title=evaluatedQs.title,
77                            html=evaluatedQs.html,
78                            markdown=evaluatedQs.markdown,
79                            category= evaluatedQs.category,
80                            media_src= evaluatedQs.media_src,
81                            level=evaluatedQs.level)
82 
83     return currentTutorial
84 
85 
86 def _resolveDynamicTutorials(tutorials_qs):
87     """
88     Evaluates a QuerySet and passes each evaluated object to the next function which returns a python
89     dictionary that contains all parameters from the object as dict. The dict is added to a list to
90     later merge the static and dynamic tutorials together.
91 
92     :param tutorials_qs:
93     :return:
94     """
95     resolvedTutorials = []
96 
97     for tutorial in tutorials_qs:
98         paramsToAdd = _resolveDynamicTutorial(tutorial)
99 
100         resolvedTutorials.append(paramsToAdd)
101 
102     return resolvedTutorials
103 
104 
105 def _gatherTutorials(id=None):
106     """
107     Collects all existing tutorials (static/dynamic) and returns them as a list. If an id is
108     specified as parameter a specific tutorial is returned filtered by id.
109 
110     :param id:
111     :return:
112     """
113 
114     # Retrieve allTutorials objects from db and cache
115     dynamicTutorialsQs = Tutorial.objects.all()
116 
117     tutorials = _resolveStaticTutorials()
118     tutorials.extend(_resolveDynamicTutorials(dynamicTutorialsQs))
119 
120     if id:
121         filteredElement = list(filter(lambda tutorial: tutorial["id"] == id, tutorials))[0]
122         return filteredElement
123 
124     return tutorials
125 
126 def _processFormInput(form):
127     tutorial = form.save(commit=False)
128     # Add more information to the dataset like date, time, contributor ...
129 
130     if tutorial.media_src:
131         matchResult = youtubeUrlRegex.match(tutorial.media_src)
132         videoId = matchResult.group(1) if matchResult else None
133         if videoId:
134             tutorial.media_src = "https://www.youtube.com/embed/" + videoId
135 
136     return tutorial
137 
138 def formattedMarkdown(markdown):
139     """
140     A parameter is used to enter a text formatted as markdown that is formatted
141     to html and returned. This functionality is implemented using Markdown2.
142 
143     :param markdown:
144     :return:
145     """
146 
147     # escapes html but also escapes html code blocks lke "exampel code:
148     #                                                    (1 tab)  code"
149     # checkbox also not rendered as expected "- [ ]"
150     markdowner = Markdown(safe_mode=True)
151     markdowner.html_removed_text = ""
152 
153     return markdowner.convert(markdown)
154 
155 
156 class ListTutorials(View):
157     def get(self, request):
158         """
159         Load and list the available tutorials.
160 
161         :param request: A HTTP-request object sent by the Django framework.
162         :return: Tutorials renderer
163         """
164 
165         # Gathering all tutorials
166 
167         tutorials = _gatherTutorials()
168 
169         return render(
170             request, 'list.html', {"tutorials": tutorials}
171         )
172 
173 
174 class TutorialDetail(View):
175     def get(self, request, tutorial_id):
176         """
177         Detail view for specific tutorial.
178 
179         :param request: A HTTP-request object sent by the Django framework.
180         :return: Tutorials renderer
181         """
182 
183         # Gathering all tutorials
184 
185         tutorial = _gatherTutorials(tutorial_id)
186 
187         return render(
188             request, 'detail.html', {"tutorial": tutorial}
189         )
190 
191 
192 class CreateNewTutorial(LoginRequiredMixin, CreateView):
193     template_name = 'add.html'
194     redirect_url = 'detail_tutorial'
195     form_class = TutorialForm
196     login_url = '/user/login/'
197     redirect_field_name = 'redirect_to'
198 
199     def form_valid(self, form):
200         """
201          validates a form and stores the values in the database and inserts a
202          value for the tutorials field html.
203 
204         :param form:
205         :return:
206         """
207 
208         tutorial = _processFormInput(form)
209         tutorial.save()
210 
211         # Convert markdown to HTML and save to db
212         _html = formattedMarkdown(tutorial.markdown)
213         addHtml = Tutorial.objects.get(pk=tutorial.id)
214         addHtml.html = _html
215         addHtml.save()
216 
217         return redirect(self.redirect_url, tutorial_id=tutorial.id)
218 
219     def addTutorialFromMarkdownFile(self):
220         pass
221 
222 
223 class EditTutorials(LoginRequiredMixin, UpdateView):
224     template_name = 'add.html'
225     redirect_url = 'detail_tutorial'
226     model = Tutorial
227     form_class = TutorialForm
228     pk_url_kwarg = 'tutorial_id'
229     login_url = '/user/login/'
230     redirect_field_name = 'redirect_to'
231 
232     def form_valid(self, form):
233         """
234         validates a form and stores the values in the database and inserts a
235          value for the tutorials field html.
236 
237         :param form:
238         :return:
239         """
240         tutorial = _processFormInput(form)
241         tutorial.save()
242 
243         _html = formattedMarkdown(tutorial.markdown)
244         addHtml = Tutorial.objects.get(pk=tutorial.id)
245         addHtml.html = _html
246         addHtml.save()
247 
248         return redirect(self.redirect_url, tutorial_id=tutorial.id)
249 
250 
251 class DeleteTutorial(LoginRequiredMixin, DeleteView):
252     template_name = 'tutorial_confirm_delete.html'
253     model = Tutorial
254     pk_url_kwarg = 'tutorial_id'
255     success_url = reverse_lazy('list_tutorials')
256     login_url = '/user/login/'
257     redirect_field_name = 'redirect_to'
258 
259 
260 
261 
262 
263 
264 
265 
266
```
--- 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/tutorials/views.py b/tutorials/views.py
--- a/tutorials/views.py
+++ b/tutorials/views.py
@@ -147,7 +147,8 @@
     # escapes html but also escapes html code blocks lke "exampel code:
     #                                                    (1 tab)  code"
     # checkbox also not rendered as expected "- [ ]"
-    markdowner = Markdown(safe_mode=True)
+    # TODO: Add syntax highliting, add css files -> https://github.com/trentm/python-markdown2/wiki/fenced-code-blocks 
+    markdowner = Markdown( extras=["break-on-newline", "fenced-code-blocks"], safe_mode=True)
     markdowner.html_removed_text = ""
 
     return markdowner.convert(markdown)
@@ -210,6 +211,7 @@
 
         # Convert markdown to HTML and save to db
         _html = formattedMarkdown(tutorial.markdown)
+        print(_html)
         addHtml = Tutorial.objects.get(pk=tutorial.id)
         addHtml.html = _html
         addHtml.save()

{"golden_diff": "diff --git a/tutorials/views.py b/tutorials/views.py\n--- a/tutorials/views.py\n+++ b/tutorials/views.py\n@@ -147,7 +147,8 @@\n     # escapes html but also escapes html code blocks lke \"exampel code:\n     #                                                    (1 tab)  code\"\n     # checkbox also not rendered as expected \"- [ ]\"\n-    markdowner = Markdown(safe_mode=True)\n+    # TODO: Add syntax highliting, add css files -> https://github.com/trentm/python-markdown2/wiki/fenced-code-blocks \n+    markdowner = Markdown( extras=[\"break-on-newline\", \"fenced-code-blocks\"], safe_mode=True)\n     markdowner.html_removed_text = \"\"\n \n     return markdowner.convert(markdown)\n@@ -210,6 +211,7 @@\n \n         # Convert markdown to HTML and save to db\n         _html = formattedMarkdown(tutorial.markdown)\n+        print(_html)\n         addHtml = Tutorial.objects.get(pk=tutorial.id)\n         addHtml.html = _html\n         addHtml.save()\n", "issue": "Tutorial form: Markdown for code does not work\nSee example tutorial\r\nhttps://openenergy-platform.org/tutorials/12/\r\n\r\nThis would be important for our beginners tutorial to work:\r\nhttps://openenergy-platform.org/tutorials/11/\r\n \r\n\r\n> See also #405 \r\n\r\n\r\n\r\n\n", "before_files": [{"content": "from django.shortcuts import render, redirect\nfrom django.views import View\nfrom django.views.generic.edit import CreateView, UpdateView, DeleteView\nfrom django.urls import exceptions, reverse_lazy\nfrom django.contrib.auth.mixins import LoginRequiredMixin\n\nimport os\nimport json\n\nfrom copy import deepcopy\n\nfrom django.conf import settings\n\nfrom markdown2 import Markdown\n\nfrom .forms import TutorialForm\nfrom .models import Tutorial\n\nimport re\n# Create your views here.\n\nyoutubeUrlRegex = re.compile('^.*youtube\\.com\\/watch\\?v=(?P<id>[A-z0-9]+)$')\n\ndef _resolveStaticTutorial(tutorial):\n    try:\n        with open(os.path.join(settings.BASE_DIR, \"examples\", \"build\", tutorial[\"fileName\"]), 'r') as buildFile:\n                buildFileContent = buildFile.read()\n\n        return {\n            \"html\": buildFileContent\n        }\n\n    except:\n        return {\"html\": \"Tutorial is missing\"}\n\n\ndef _resolveStaticTutorials():\n    resolvedTutorials = []\n\n    # Load list of static tutorials\n\n    try:\n        with open(os.path.join(settings.BASE_DIR, \"examples\", \"build\", 'meta.json'), 'r') as metaFile:\n            metaContent = json.load(metaFile)\n\n            for tutorial in metaContent:\n                rTut = _resolveStaticTutorial(tutorial)\n                resolvedTutorials.append({\n                    'id': tutorial['id'],\n                    'fileName': tutorial['fileName'],\n                    'title': tutorial['title'] or tutorial['fileName'],\n                    'html': rTut['html'],\n                })\n\n            return sorted(resolvedTutorials, key=lambda x: x[\"title\"])\n    except Exception as e:\n        print('Static tutorials could not be loaded, error=%s' % e)\n        # If we do not have a generated meta.json or we cannot read them, we just do not return any static\n        # tutorials. This is completly fine and dynamic tutorials can be used like normal.\n        return []\n\n\ndef _resolveDynamicTutorial(evaluatedQs):\n    \"\"\"\n\n\n    :param evaluatedQs: Evaluated queryset object\n    :return:\n    \"\"\"\n\n    # Initialize dict that stores a tutorial\n    currentTutorial = {'id': '', 'title': '', 'html': '', 'markdown': '', 'category': '', 'media_src': '', 'level': ''}\n\n    # populate dict\n    currentTutorial.update(id=str(evaluatedQs.id),\n                           title=evaluatedQs.title,\n                           html=evaluatedQs.html,\n                           markdown=evaluatedQs.markdown,\n                           category= evaluatedQs.category,\n                           media_src= evaluatedQs.media_src,\n                           level=evaluatedQs.level)\n\n    return currentTutorial\n\n\ndef _resolveDynamicTutorials(tutorials_qs):\n    \"\"\"\n    Evaluates a QuerySet and passes each evaluated object to the next function which returns a python\n    dictionary that contains all parameters from the object as dict. The dict is added to a list to\n    later merge the static and dynamic tutorials together.\n\n    :param tutorials_qs:\n    :return:\n    \"\"\"\n    resolvedTutorials = []\n\n    for tutorial in tutorials_qs:\n        paramsToAdd = _resolveDynamicTutorial(tutorial)\n\n        resolvedTutorials.append(paramsToAdd)\n\n    return resolvedTutorials\n\n\ndef _gatherTutorials(id=None):\n    \"\"\"\n    Collects all existing tutorials (static/dynamic) and returns them as a list. If an id is\n    specified as parameter a specific tutorial is returned filtered by id.\n\n    :param id:\n    :return:\n    \"\"\"\n\n    # Retrieve allTutorials objects from db and cache\n    dynamicTutorialsQs = Tutorial.objects.all()\n\n    tutorials = _resolveStaticTutorials()\n    tutorials.extend(_resolveDynamicTutorials(dynamicTutorialsQs))\n\n    if id:\n        filteredElement = list(filter(lambda tutorial: tutorial[\"id\"] == id, tutorials))[0]\n        return filteredElement\n\n    return tutorials\n\ndef _processFormInput(form):\n    tutorial = form.save(commit=False)\n    # Add more information to the dataset like date, time, contributor ...\n\n    if tutorial.media_src:\n        matchResult = youtubeUrlRegex.match(tutorial.media_src)\n        videoId = matchResult.group(1) if matchResult else None\n        if videoId:\n            tutorial.media_src = \"https://www.youtube.com/embed/\" + videoId\n\n    return tutorial\n\ndef formattedMarkdown(markdown):\n    \"\"\"\n    A parameter is used to enter a text formatted as markdown that is formatted\n    to html and returned. This functionality is implemented using Markdown2.\n\n    :param markdown:\n    :return:\n    \"\"\"\n\n    # escapes html but also escapes html code blocks lke \"exampel code:\n    #                                                    (1 tab)  code\"\n    # checkbox also not rendered as expected \"- [ ]\"\n    markdowner = Markdown(safe_mode=True)\n    markdowner.html_removed_text = \"\"\n\n    return markdowner.convert(markdown)\n\n\nclass ListTutorials(View):\n    def get(self, request):\n        \"\"\"\n        Load and list the available tutorials.\n\n        :param request: A HTTP-request object sent by the Django framework.\n        :return: Tutorials renderer\n        \"\"\"\n\n        # Gathering all tutorials\n\n        tutorials = _gatherTutorials()\n\n        return render(\n            request, 'list.html', {\"tutorials\": tutorials}\n        )\n\n\nclass TutorialDetail(View):\n    def get(self, request, tutorial_id):\n        \"\"\"\n        Detail view for specific tutorial.\n\n        :param request: A HTTP-request object sent by the Django framework.\n        :return: Tutorials renderer\n        \"\"\"\n\n        # Gathering all tutorials\n\n        tutorial = _gatherTutorials(tutorial_id)\n\n        return render(\n            request, 'detail.html', {\"tutorial\": tutorial}\n        )\n\n\nclass CreateNewTutorial(LoginRequiredMixin, CreateView):\n    template_name = 'add.html'\n    redirect_url = 'detail_tutorial'\n    form_class = TutorialForm\n    login_url = '/user/login/'\n    redirect_field_name = 'redirect_to'\n\n    def form_valid(self, form):\n        \"\"\"\n         validates a form and stores the values in the database and inserts a\n         value for the tutorials field html.\n\n        :param form:\n        :return:\n        \"\"\"\n\n        tutorial = _processFormInput(form)\n        tutorial.save()\n\n        # Convert markdown to HTML and save to db\n        _html = formattedMarkdown(tutorial.markdown)\n        addHtml = Tutorial.objects.get(pk=tutorial.id)\n        addHtml.html = _html\n        addHtml.save()\n\n        return redirect(self.redirect_url, tutorial_id=tutorial.id)\n\n    def addTutorialFromMarkdownFile(self):\n        pass\n\n\nclass EditTutorials(LoginRequiredMixin, UpdateView):\n    template_name = 'add.html'\n    redirect_url = 'detail_tutorial'\n    model = Tutorial\n    form_class = TutorialForm\n    pk_url_kwarg = 'tutorial_id'\n    login_url = '/user/login/'\n    redirect_field_name = 'redirect_to'\n\n    def form_valid(self, form):\n        \"\"\"\n        validates a form and stores the values in the database and inserts a\n         value for the tutorials field html.\n\n        :param form:\n        :return:\n        \"\"\"\n        tutorial = _processFormInput(form)\n        tutorial.save()\n\n        _html = formattedMarkdown(tutorial.markdown)\n        addHtml = Tutorial.objects.get(pk=tutorial.id)\n        addHtml.html = _html\n        addHtml.save()\n\n        return redirect(self.redirect_url, tutorial_id=tutorial.id)\n\n\nclass DeleteTutorial(LoginRequiredMixin, DeleteView):\n    template_name = 'tutorial_confirm_delete.html'\n    model = Tutorial\n    pk_url_kwarg = 'tutorial_id'\n    success_url = reverse_lazy('list_tutorials')\n    login_url = '/user/login/'\n    redirect_field_name = 'redirect_to'\n\n\n\n\n\n\n\n\n", "path": "tutorials/views.py"}], "after_files": [{"content": "from django.shortcuts import render, redirect\nfrom django.views import View\nfrom django.views.generic.edit import CreateView, UpdateView, DeleteView\nfrom django.urls import exceptions, reverse_lazy\nfrom django.contrib.auth.mixins import LoginRequiredMixin\n\nimport os\nimport json\n\nfrom copy import deepcopy\n\nfrom django.conf import settings\n\nfrom markdown2 import Markdown\n\nfrom .forms import TutorialForm\nfrom .models import Tutorial\n\nimport re\n# Create your views here.\n\nyoutubeUrlRegex = re.compile('^.*youtube\\.com\\/watch\\?v=(?P<id>[A-z0-9]+)$')\n\ndef _resolveStaticTutorial(tutorial):\n    try:\n        with open(os.path.join(settings.BASE_DIR, \"examples\", \"build\", tutorial[\"fileName\"]), 'r') as buildFile:\n                buildFileContent = buildFile.read()\n\n        return {\n            \"html\": buildFileContent\n        }\n\n    except:\n        return {\"html\": \"Tutorial is missing\"}\n\n\ndef _resolveStaticTutorials():\n    resolvedTutorials = []\n\n    # Load list of static tutorials\n\n    try:\n        with open(os.path.join(settings.BASE_DIR, \"examples\", \"build\", 'meta.json'), 'r') as metaFile:\n            metaContent = json.load(metaFile)\n\n            for tutorial in metaContent:\n                rTut = _resolveStaticTutorial(tutorial)\n                resolvedTutorials.append({\n                    'id': tutorial['id'],\n                    'fileName': tutorial['fileName'],\n                    'title': tutorial['title'] or tutorial['fileName'],\n                    'html': rTut['html'],\n                })\n\n            return sorted(resolvedTutorials, key=lambda x: x[\"title\"])\n    except Exception as e:\n        print('Static tutorials could not be loaded, error=%s' % e)\n        # If we do not have a generated meta.json or we cannot read them, we just do not return any static\n        # tutorials. This is completly fine and dynamic tutorials can be used like normal.\n        return []\n\n\ndef _resolveDynamicTutorial(evaluatedQs):\n    \"\"\"\n\n\n    :param evaluatedQs: Evaluated queryset object\n    :return:\n    \"\"\"\n\n    # Initialize dict that stores a tutorial\n    currentTutorial = {'id': '', 'title': '', 'html': '', 'markdown': '', 'category': '', 'media_src': '', 'level': ''}\n\n    # populate dict\n    currentTutorial.update(id=str(evaluatedQs.id),\n                           title=evaluatedQs.title,\n                           html=evaluatedQs.html,\n                           markdown=evaluatedQs.markdown,\n                           category= evaluatedQs.category,\n                           media_src= evaluatedQs.media_src,\n                           level=evaluatedQs.level)\n\n    return currentTutorial\n\n\ndef _resolveDynamicTutorials(tutorials_qs):\n    \"\"\"\n    Evaluates a QuerySet and passes each evaluated object to the next function which returns a python\n    dictionary that contains all parameters from the object as dict. The dict is added to a list to\n    later merge the static and dynamic tutorials together.\n\n    :param tutorials_qs:\n    :return:\n    \"\"\"\n    resolvedTutorials = []\n\n    for tutorial in tutorials_qs:\n        paramsToAdd = _resolveDynamicTutorial(tutorial)\n\n        resolvedTutorials.append(paramsToAdd)\n\n    return resolvedTutorials\n\n\ndef _gatherTutorials(id=None):\n    \"\"\"\n    Collects all existing tutorials (static/dynamic) and returns them as a list. If an id is\n    specified as parameter a specific tutorial is returned filtered by id.\n\n    :param id:\n    :return:\n    \"\"\"\n\n    # Retrieve allTutorials objects from db and cache\n    dynamicTutorialsQs = Tutorial.objects.all()\n\n    tutorials = _resolveStaticTutorials()\n    tutorials.extend(_resolveDynamicTutorials(dynamicTutorialsQs))\n\n    if id:\n        filteredElement = list(filter(lambda tutorial: tutorial[\"id\"] == id, tutorials))[0]\n        return filteredElement\n\n    return tutorials\n\ndef _processFormInput(form):\n    tutorial = form.save(commit=False)\n    # Add more information to the dataset like date, time, contributor ...\n\n    if tutorial.media_src:\n        matchResult = youtubeUrlRegex.match(tutorial.media_src)\n        videoId = matchResult.group(1) if matchResult else None\n        if videoId:\n            tutorial.media_src = \"https://www.youtube.com/embed/\" + videoId\n\n    return tutorial\n\ndef formattedMarkdown(markdown):\n    \"\"\"\n    A parameter is used to enter a text formatted as markdown that is formatted\n    to html and returned. This functionality is implemented using Markdown2.\n\n    :param markdown:\n    :return:\n    \"\"\"\n\n    # escapes html but also escapes html code blocks lke \"exampel code:\n    #                                                    (1 tab)  code\"\n    # checkbox also not rendered as expected \"- [ ]\"\n    # TODO: Add syntax highliting, add css files -> https://github.com/trentm/python-markdown2/wiki/fenced-code-blocks \n    markdowner = Markdown( extras=[\"break-on-newline\", \"fenced-code-blocks\"], safe_mode=True)\n    markdowner.html_removed_text = \"\"\n\n    return markdowner.convert(markdown)\n\n\nclass ListTutorials(View):\n    def get(self, request):\n        \"\"\"\n        Load and list the available tutorials.\n\n        :param request: A HTTP-request object sent by the Django framework.\n        :return: Tutorials renderer\n        \"\"\"\n\n        # Gathering all tutorials\n\n        tutorials = _gatherTutorials()\n\n        return render(\n            request, 'list.html', {\"tutorials\": tutorials}\n        )\n\n\nclass TutorialDetail(View):\n    def get(self, request, tutorial_id):\n        \"\"\"\n        Detail view for specific tutorial.\n\n        :param request: A HTTP-request object sent by the Django framework.\n        :return: Tutorials renderer\n        \"\"\"\n\n        # Gathering all tutorials\n\n        tutorial = _gatherTutorials(tutorial_id)\n\n        return render(\n            request, 'detail.html', {\"tutorial\": tutorial}\n        )\n\n\nclass CreateNewTutorial(LoginRequiredMixin, CreateView):\n    template_name = 'add.html'\n    redirect_url = 'detail_tutorial'\n    form_class = TutorialForm\n    login_url = '/user/login/'\n    redirect_field_name = 'redirect_to'\n\n    def form_valid(self, form):\n        \"\"\"\n         validates a form and stores the values in the database and inserts a\n         value for the tutorials field html.\n\n        :param form:\n        :return:\n        \"\"\"\n\n        tutorial = _processFormInput(form)\n        tutorial.save()\n\n        # Convert markdown to HTML and save to db\n        _html = formattedMarkdown(tutorial.markdown)\n        print(_html)\n        addHtml = Tutorial.objects.get(pk=tutorial.id)\n        addHtml.html = _html\n        addHtml.save()\n\n        return redirect(self.redirect_url, tutorial_id=tutorial.id)\n\n    def addTutorialFromMarkdownFile(self):\n        pass\n\n\nclass EditTutorials(LoginRequiredMixin, UpdateView):\n    template_name = 'add.html'\n    redirect_url = 'detail_tutorial'\n    model = Tutorial\n    form_class = TutorialForm\n    pk_url_kwarg = 'tutorial_id'\n    login_url = '/user/login/'\n    redirect_field_name = 'redirect_to'\n\n    def form_valid(self, form):\n        \"\"\"\n        validates a form and stores the values in the database and inserts a\n         value for the tutorials field html.\n\n        :param form:\n        :return:\n        \"\"\"\n        tutorial = _processFormInput(form)\n        tutorial.save()\n\n        _html = formattedMarkdown(tutorial.markdown)\n        addHtml = Tutorial.objects.get(pk=tutorial.id)\n        addHtml.html = _html\n        addHtml.save()\n\n        return redirect(self.redirect_url, tutorial_id=tutorial.id)\n\n\nclass DeleteTutorial(LoginRequiredMixin, DeleteView):\n    template_name = 'tutorial_confirm_delete.html'\n    model = Tutorial\n    pk_url_kwarg = 'tutorial_id'\n    success_url = reverse_lazy('list_tutorials')\n    login_url = '/user/login/'\n    redirect_field_name = 'redirect_to'\n\n\n\n\n\n\n\n\n", "path": "tutorials/views.py"}]}