Django - create code blocks in html templates - django

I would like to create a web page that will display data I have in a table inside a code block just the way it is here, even with a copy function.
I can already display the data on the page, I just like to have it formatted in a pretty box, maybe even with syntax highlights, I looked at Pygments but I can't get it to work.
Below is a sample code block that I would like to re-create in my Django app.
Please don't pay attention to the actual code, this is only a sample.
I would appreciate if you could please let me know in detail how to implement this.
# Python Program to find the area of triangle
a = 5
b = 6
c = 7
# Uncomment below to take inputs from the user
# a = float(input('Enter first side: '))
# b = float(input('Enter second side: '))
# c = float(input('Enter third side: '))
# calculate the semi-perimeter
s = (a + b + c) / 2
# calculate the area
area = (s*(s-a)*(s-b)*(s-c)) ** 0.5
print('The area of the triangle is %0.2f' %area)

Honestly, your question is more related to CSS and Javascript than Python / Django.
This took me a while...Based on what you said, I will assume you know the basics of Django.
models.py
from django.db import models
class Codeblock(models.Model):
text = models.TextField()
...
views.py
from .models import Codeblock
def codes(request):
codeblocks = Codeblock.objects.all()
return render(request, 'list_codes.html', {'codeblocks': codeblocks})
To format code blocks you can use HTML pre and code tags (Bootstrap 5 examples):
<pre><code>{{codeblocks.text}}</code></pre>
The tricky part was trying to find a way to hightlight the syntax. After a few dead ends I have found highlight.js that worked very well. It has documentation on basic usage and various themes for you to play with, you can test them using this CDN library, it is also possible to write your own theme.
There was one last problem related on how to copy the text. Although it is easy to copy text to clipboard, its not an easy task (at least for me) to have a styled button placed in the right place. To not extend myself, after a while I found this highlightjs-copy project, that not only copy the text to clipboard but has a perfect button in the right place.
With that being said, at last, here is an example:
list_codes.html
<!DOCTYPE html>
<html>
<head>
<!-- bootstrap -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<!-- highlight.js -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/base16/ashes.min.css" integrity="sha512-KX15mI6Sw0VzQyAOf4MAPS9BZ0tWXyZrGPHKSkqDmy40Jl+79f8ltpj6FvLJ+3obnH56ww0ukclsd6xGAxb5mA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
<script>hljs.highlightAll();</script>
<!-- highlightjs-copy -->
<script src="https://unpkg.com/highlightjs-copy/dist/highlightjs-copy.min.js"></script>
<link
rel="stylesheet"
href="https://unpkg.com/highlightjs-copy/dist/highlightjs-copy.min.css"
/>
<script>hljs.addPlugin(new CopyButtonPlugin());</script>
</head>
<body style="background-color: hsl(0,0%,22.5%);">
{% for codeblock in codeblocks %}
<div class="container">
<!-- Need to be in one line or will not render correctly -->
<pre><code class="language-python">{{codeblock.text}}</code></pre>
</div>
{% endfor %}
</body>
</html>

Related

Stylized HTML fields in Django admin

I Have TextField to store HTML text. I want to colorize HTML tags. I use TinyMCE but didn't need an HTML editor like WordPress just simple to colorize like IDE, Search a lot but didn't find anything useful, So if you can help I appreciate it.
My field:
I want output like this but changeable:
Using a code editor in Django admin Textarea
The following is implemented with CodeMirror but you can use any other library (Monaco, etc).
Final result:
For all the libraries, we need to add some library specific javascript and stylesheet plus some custom code for integration.
Django has pretty flexible templating to enable this. We can override the entire template or specific blocks. Detailed documentation can be fond here.
To integration CodeMirror, we can override the admin/base.html 's extrahead block. We will include the required js/css, one extra css for theming and some js to find and apply CodeMirror.
Here, I have create a admin/base.html inside my project's configured template directory. This will apply to all the apps and models. There are ways to target an app or model individually - check the office docs.
This works for JSONField data. You will have to tweak a bit to format
html or any other language.
Inspect the page and find id of the textarea you want to target
<!-- tested with Django 3.2.9 -->
{% extends "admin/base.html" %}
{% block extrahead %}
{{ block.super }}
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.0/codemirror.min.js" crossorigin="anonymous"
referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.0/codemirror.min.css"
crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.0/theme/oceanic-next.min.css"
crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.0/mode/javascript/javascript.min.js"
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script type="text/javascript">
window.addEventListener('load', (event) => {
const target = document.getElementById("id_data");
target.value = JSON.stringify(JSON.parse(target.value), null, ' ');
const config = {
mode: 'javascript',
theme: 'oceanic-next',
lineNumbers: true,
lineWrapping: true
}
const jsonCodeMirror = CodeMirror.fromTextArea(target, config);
jsonCodeMirror.setSize("100%", 600);
});
</script>
{% endblock %}
Multiple textarea inputs can be targeted as well with get element with classname and then looping over the result set and applying the same logic.
For html formatting,
you can use this https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.0/mode/htmlmixed/htmlmixed.min.js instead of javascript. Delete the json stringify statement. Change mode to htmlmixed.
Don't need to override any template
solved by integrating django-ace field and in this we have support for CSS, python, HTML etc also.
Simply use this in django forms and provide the form in django model admin class
admin file
from appname import forms
#admin.register(models.Table)
class TableModelAdmin(admin.ModelAdmin):
form = forms.TableModelForm
form file
from django import forms
from django_ace import AceWidget
class TableModelForm(forms.ModelForm):
class Meta:
model = models.Table
fields = '__all__'
widgets = {
'columns': AceWidget(
mode='json',
theme='None',
width='1200px',
height='500px',
fontsize='18px',
showprintmargin=False,
),
}

Mako inhereting from multiple files

I have a pyramid application with multiple views each depending on a single mako template. The views are quite complicated and bug free, so I don't want to split or merge views, and by extension, the corresponding templates.
However, I would like a single view to represent all the others. Merging all the pyramid views and templates is practically not an option.
For example, I have a login view & template and a signup view & template. Now I want my root page to contain both of them. Both login and signup inherit from base.mak, which contains common scripts and style sheet imports. The following is a pictorial representation of the mako import structure I want.
base.mak
/ \
login.mak signup.mak
\ /
root.mak
Alternatively, I tried chaining them as such:
base -> login -> signup -> root
However, I think that the views no longer talk to their respective templates.
My problem comes in when I do the 3rd chain (login.mak -> signup). I'll post analogous and extract code below, since my full code is a bit long (If more code is needed, feel free to shout).
base.mak:
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>
${next.title()}
</title>
#Imports
${next.head()}
</head>
<body>
<div id = "content">
${next.body()}
</div>
</body>
</html>
login.mak:
<%inherit file="base.mak"/>
<%def name="title()">
${next.title()}
</%def>
<%def name="head()">
${next.head()}
</%def>
<div id="login">
<div id="message">
${sMessage}
</div>
<div id="form">
<form action="${url}" method="post"> <--- url returned in views.py
...
</div>
${next.body()}
signup.mak:
<%inherit file="login.mak"/>
<%def name="title()">
</%def>
<%def name="head()">
</%def>
<div id="box">
...
</div>
Now my problem here is that my url returned from my views is undefined when I try to inherit as in above.
Then of course if I get this working, adding base.mak to to inherit from signup should be trivial.
I assume that there is a simple fix for this, but I can't find an example/explanation on how to do this in pyramid, where the templates actually do stuff.
Alternatively, Is there another way to bring together multiple pyramid views and templates into a single view?
Ok, I figured it out. One has to use mako's <%include/>, and then there is no complicated inheritance structure. So, now my files look like this:
root.mak
<%inherit file="base.mak"/>
<%def name="title()">
Welcome
</%def>
<%def name="head()">
</%def>
<%include file="login.mak"/>
<%include file="signup.mak"/>
login.mak:
<%inherit file="base.mak"/>
<%def name="title()">
</%def>
<%def name="head()">
<link rel="stylesheet" type="text/css" href="${request.static_url(...
</%def>
<div id="login">
<div id=".....
</div>
and the same structure with signup.mak. base.mak still looks the same as in the question above.
Now, if you're using pyramid (I assume another framework will work the same), and you have views that receive and pass information from forms for example, then turn them into normal functions (without #view_config(renderer='path/file.mak') and place their functionality into the parent view function, in my case root. In other words:
#view_config(renderer='pyramidapp:templates/root.mak',
context=Root,
name="")
#forbidden_view_config(renderer='pyramidapp:templates/root.mak')
def root(self):
xLoginRet = login(self)
xSignupRet = signup(self)
#logic and functionality for both, return stuff to go to base.mak

Webpy Template Function syntax

I am trying to write a web application using Webpy. My application gets info on outputs that are ether off or on. I would like to use an image to show an "on" button or an "off" button.
The data sent to the Webpy template is a dictionary of outputs (key defines the output) and a value (in String type) the value is either '1' for on or '0' for off.
My first thought was to write a function within my template to return the image file based on the value like this:
template_tester_simple.py:
import web
render = web.template.render('templates/')
urls = ('/', 'index')
template_tester_simple = web.application(urls, globals())
class index:
def GET(self):
return render.test_func(data)
def add_data():
data = {'currSet':'75','currTemp':'60','currMode':'Off',
'Cool':'1', 'Heat':'1', 'RevValve':'1', 'EmHeat':'1','Fan':'1',}
return data
data = add_data()
if __name__=="__main__":
web.internalerror = web.debugerror
template_tester_simple.run()
and My test_func.html template:
$def with (data)
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
$code:
def getSwitchImg(item):
x=""
if (item=='1'):
x="<img src= '../static/switch_on.png'></img>"
else: "<img src= '../static/switch_off.png'></img>"
return x
<body>
<ul>
<li><strong>Cooling</strong><p>
$getSwitchImg($data['Cool'])
</p></li>
<li><strong>Reversing Valve</strong><p>
$getSwitchImg($data['RevValve'])
</p></li>
</ul>
</body>
This returns a Syntax Error as:
at /
invalid syntax Template traceback: File 'templates/test_func.html', line 23 None (test_func.html, line 23)
I could not figure out the Syntax error. It lists a line that is the closing tag of my unordered list , which does not make any sense since it is past all the python code. So It must be something in WebPy template system that I do not understand. Is the function block not getting "closed" properly?
Out of frustration, I then changed my template to the following, using the same template_tester_simple.py:
$def with (data)
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
<ul>
<li><strong>Cooling</strong>
$if data['Cool'] == '1':
<img src="../static/switch_on.png" height="15px" width="40px"></img>
$else:
<img src="../static/switch_off.png" height="15px" width="40px"></img>
</li>
<li><strong>Heating</strong>
$if data['Heat'] == '1':
<img src="../static/switch_on.png" height="15px" width="40px"></img>
$else:
<img src="../static/switch_off.png" height="15px" width="40px"></img>
</li>
</ul>
</body>
This works, but I am not defining the function I wanted to use. I am forced to copy/paste basically the same code over and over. As I develop this project further, I plan to add more switches, therefore more digital outputs. If I could get the first template code to work, it will make expanding my app much easier. Also I want to understand the syntax associated with functions within WebPy templates. I have read the templator tutorial on the Webpy website. I thought that once you used "code:" you went to standard python syntax, then once you come out of the indented block, it should be standard HTML. Could someone please explain this syntax, and therefore my error.
I don't know if it's just the way you copy/paste your code here but I've seen an indention problem here.
def getSwitchImg(item):
x=""
if (item=='1'):
x="<img src= '../static/switch_on.png'></img>"
else: "<img src= '../static/switch_off.png'></img>"
return x
It's supposed to be:
def getSwitchImg(item):
x=""
if (item=='1'):
x="<img src= '../static/switch_on.png'></img>"
else:
x="<img src= '../static/switch_off.png'></img>"
return x

How to render a template with dynamic CSS?

I want to create a dynamic CSS file in a view and then render a template which loads that CSS file. Depending on the arguments given to the view, the CSS may have different values at certain places every time the view is called. How would I go about doing that? (I should add that I have no experience with writing files in Python/Django.)
Here is a simplified example of how I think it should work:
# urls.py
urlpatterns = patterns('',
(r'^myview/(?P<color>[0-9a-f]{6})/$', create_css_file),
)
# views.py
def create_css_file(request, color):
raw = "#charset 'UTF-8';\n\n"
raw += "body {\n"
raw += " color: #" + color + ";\n"
raw += "}\n\n"
f = open('mydynamic.css', 'r+')
f.write(raw)
return render_to_response('mytemplate.html', locals())
# mytemplate.html
{% extends "base.html" %}
{% block head %}
<link rel="stylesheet" media="screen" href="{{ f.name }}" />
{% endblock %}
For some reason, that doesn't work, although in the resulting HTML page's source code, it looks like the CSS file is loaded correctly. The f even arrives at the template correctly, because I can see its contents when I change the <link>... line to
<link rel="stylesheet" media="screen" href="{{ f }}" />
(finstead of f.name). But the HTML is rendered without the desired color setting. Can anybody tell my why that is?
I suspected some path issue, and I toyed around quite a bit with different paths, but to no avail.
Please do not advise me to prepare several hardcoded CSS files (as I have found in answers to similar questions), because there will be several hundred possibilities.
If you absolutely need to you can just create a css file dynamically.
You can create an entry in your urls.py. You can name urls anything you want this could look like a static .css file to the outside world but would be created dynamically.
(r'^(?P<color>[0-9a-f]{6})/dynamic.css$', dynamic_css)
def dynamic_css(request, color):
"""
Create a css file based on a color criteria,
or any other complicated calculations necessary
"""
# do custom element positionting.
return render_to_response('dynamic.css', {'color': color})
# dynamic.css
body {
background-color: {{ color }}
}
There is no reason to write css files for this. Now you can just include
<link rel="styleshee" type="text/css" href="/purple/dymamic.css" />
In your template.
As mentioned this shouldn't be used just for changing one color. That could be done in your template. If you had to do something like this it would probably be a good idea to implement cacheing as every time a page is requested it has to dynamically generate .css that could be performance overhead. This is more of an example to show you can name urls.py entries anything you want. And include them in any way you want in html ie. if you needed a custom javascript file dynamically created you could create an entry in urls.py and then create a view that generates a .js file.
views.py:
def create_css_file(request, color):
f = color
return render_to_response('mytemplate.html', locals())
template:
<body style = "color:{{f}}!important;">
Don't create css file on the fly it is unnecessary.
I went with #CatPlusPlus's suggestion: Calculating the necessary values in a view and passing the template a very long string (raw) which contains the entire CSS. In the template, I include it like so:
<style media="screen">{{ raw|safe }}</style>
Thanks everyone for your efforts!

Generate barcodes in Django site

I want to add barcode generation in a Django site and wonder what the best library or api would be. My first preference is something callable from Python - either written in Python or a C/C++ lib that I can wrap with ctypes/SWIG. Otherwise I can call out to the command line if must be.
I need at least EAN and UPC symbologies.
I've tried pybarcode but the image quality is too low. And Elaphe looks promising but from the Python interpreter all I could make was a QR Code -- EAN and UPC errored out (maybe because the syntax/usage was unclear from the documentation).
Use pybarcode and generate the barcode as SVG: http://packages.python.org/pyBarcode/barcode.html#creating-barcodes-as-svg
No problem of image quality in that case.
This thread is quite old, but in case anyone else is looking for an answer to this... code39 is a font, as are most types of barcode. You can simply use google fonts:
https://fonts.google.com/specimen/Libre+Barcode+39+Extended+Text?selection.family=Libre+Barcode+39+Extended+Text
Aside from that option, you could host static files, one solution could be this project on github:
https://github.com/Holger-Will/code-39-font
In that project all you need are the files associated with the size you want, and the code39_all.css file. The rest you could delete, if you like.
For your reference, I'm using both here:
{% load staticfiles %}
{% load static %}
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Libre+Barcode+39+Extended+Text" rel="stylesheet">
<link rel="stylesheet" href="{% static 'code-39-font-master/code39_all.css' %}"/>
</head>
<body>
<style>
body {
font-family: 'Libre Barcode 39 Extended Text', cursive;
font-size: 48px;
}
</style>
<div>I'm just a code39 google font</div>
<div><class="code_39_S">I'm generated with static files!</div>
</body>
</html>
reportlab could be a good alternative to pybarcode, especially when using some of its other features.
There is a howto for barcodes in Django with reportlab, works well for me.
https://code.djangoproject.com/wiki/Barcodes