I'm currently trying to create a simple website using Django, with ckeditor for form fields. I would also like to integrate some Mathematics into my forms, hence why I downloaded the Mathematical Formulas plugin for ckeditor.
I followed this tutorial to implement the plugin but MathJax doesn't work.
This is what I added to my settings.py file
CKEDITOR_CONFIGS = {
'default': {
'toolbar':'full',
'height': '400px',
'width': '100%',
'extraPlugins': ','.join(
[
'mathjax',
'widget',
'lineutils',
'dialog',
'clipboard',
]),
},
}
I copied the MathJax folder I downloaded into my project's static directory. I then refer to this in my models.py file:
from django.db import models
from django.contrib.auth.models import User
from ckeditor.fields import RichTextField
class Entry(models.Model):
entry_title = models.CharField(max_length=100)
#entry_text = models.TextField()
entry_text = RichTextField(blank = True, null = True,config_name = 'default', external_plugin_resources=[(
'mathjax',
'/static/entries/vendor/ckeditor_plugins/mathjax/',
'plugin.js',
)])
entry_date = models.DateTimeField(auto_now_add = True)
entry_author = models.ForeignKey(User, on_delete = models.CASCADE)
class Meta:
verbose_name_plural = "entries"
def __str__(self):
return f'{self.entry_title}'
When I use my form, I can see the mathematical formulas symbol:
When I click on it, ckeditor gives me the freedom to type whatever I want into the Tex field:
However, it doesn't give me a preview of what it will look like after it has been rendered.
This contradicts with the Mathematical Formula website, which gives an example of what it should look like:
Furthermore, when I click ok with my dummy Tex input, it doesn't show anything in the ckeditor box. This is followed by a message in my terminal Not Found: /create_entry/undefined and "GET /create_entry/undefined HTTP/1.1" 404 2644. 'create_entry' is a urlpattern I used when creating a form.
When I submit a form with some math in it, I cannot physically see the maths in the ckeditor field - only a blue cursor:
However, upon viewing this post after submission, the math renders:
I'm not sure if this is because I added this javascript in my base.html file:
<script type="text/javascript" async
src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_CHTML">
</script>
Any help is appreciated, Thanks.
EDIT:
I copied this code into my settings.py file and it works:
# CKEditor UI and plugins configuration
CKEDITOR_CONFIGS = {
'default': {
# Toolbar configuration
# name - Toolbar name
# items - The buttons enabled in the toolbar
'toolbar_DefaultToolbarConfig': [
{
'name': 'basicstyles',
'items': ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript',
'Superscript', ],
},
{
'name': 'clipboard',
'items': ['Undo', 'Redo', ],
},
{
'name': 'paragraph',
'items': ['NumberedList', 'BulletedList', 'Outdent', 'Indent',
'HorizontalRule', 'JustifyLeft', 'JustifyCenter',
'JustifyRight', 'JustifyBlock', ],
},
{
'name': 'format',
'items': ['Format', ],
},
{
'name': 'extra',
'items': ['Link', 'Unlink', 'Blockquote', 'Image', 'Table',
'CodeSnippet', 'Mathjax', 'Embed', ],
},
{
'name': 'source',
'items': ['Maximize', 'Source', ],
},
],
# This hides the default title provided by CKEditor
'title': False,
# Use this toolbar
'toolbar': 'DefaultToolbarConfig',
# Which tags to allow in format tab
'format_tags': 'p;h1;h2',
# Remove these dialog tabs (semicolon separated dialog:tab)
'removeDialogTabs': ';'.join([
'image:advanced',
'image:Link',
'link:upload',
'table:advanced',
'tableProperties:advanced',
]),
'linkShowTargetTab': False,
'linkShowAdvancedTab': False,
# CKEditor height and width settings
'height': '250px',
'width': 'auto',
'forcePasteAsPlainText ': True,
# Class used inside span to render mathematical formulae using latex
'mathJaxClass': 'mathjax-latex',
# Mathjax library link to be used to render mathematical formulae
'mathJaxLib': 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_SVG',
# Tab = 4 spaces inside the editor
'tabSpaces': 4,
# Extra plugins to be used in the editor
'extraPlugins': ','.join([
# 'devtools', # Shows a tooltip in dialog boxes for developers
'mathjax', # Used to render mathematical formulae
'codesnippet', # Used to add code snippets
'image2', # Loads new and better image dialog
'embed', # Used for embedding media (YouTube/Slideshare etc)
'tableresize', # Used to allow resizing of columns in tables
]),
}
}
I found it on this website.
I copied this code into my settings.py file and it works:
CKEDITOR_CONFIGS = {
'default': {
# Toolbar configuration
# name - Toolbar name
# items - The buttons enabled in the toolbar
'toolbar_DefaultToolbarConfig': [
{
'name': 'basicstyles',
'items': ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript',
'Superscript', ],
},
{
'name': 'clipboard',
'items': ['Undo', 'Redo', ],
},
{
'name': 'paragraph',
'items': ['NumberedList', 'BulletedList', 'Outdent', 'Indent',
'HorizontalRule', 'JustifyLeft', 'JustifyCenter',
'JustifyRight', 'JustifyBlock', ],
},
{
'name': 'format',
'items': ['Format', ],
},
{
'name': 'extra',
'items': ['Link', 'Unlink', 'Blockquote', 'Image', 'Table',
'CodeSnippet', 'Mathjax', 'Embed', ],
},
{
'name': 'source',
'items': ['Maximize', 'Source', ],
},
],
# This hides the default title provided by CKEditor
'title': False,
# Use this toolbar
'toolbar': 'DefaultToolbarConfig',
# Which tags to allow in format tab
'format_tags': 'p;h1;h2',
# Remove these dialog tabs (semicolon separated dialog:tab)
'removeDialogTabs': ';'.join([
'image:advanced',
'image:Link',
'link:upload',
'table:advanced',
'tableProperties:advanced',
]),
'linkShowTargetTab': False,
'linkShowAdvancedTab': False,
# CKEditor height and width settings
'height': '250px',
'width': 'auto',
'forcePasteAsPlainText ': True,
# Class used inside span to render mathematical formulae using latex
'mathJaxClass': 'mathjax-latex',
# Mathjax library link to be used to render mathematical formulae
'mathJaxLib': 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_SVG',
# Tab = 4 spaces inside the editor
'tabSpaces': 4,
# Extra plugins to be used in the editor
'extraPlugins': ','.join([
# 'devtools', # Shows a tooltip in dialog boxes for developers
'mathjax', # Used to render mathematical formulae
'codesnippet', # Used to add code snippets
'image2', # Loads new and better image dialog
'embed', # Used for embedding media (YouTube/Slideshare etc)
'tableresize', # Used to allow resizing of columns in tables
]),
}
}
It seems like I didn't include a line which rendered the Latex inside of the preview.
In CKEDITOR config according to the docs you need to specify the mathjax path.
General docs with example at bottom: https://ckeditor.com/docs/ckeditor4/latest/examples/mathjax.html
Path config variable need: https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_config.html#cfg-mathJaxLib
I would like to have an action after given certain output from PyInquirer. The idea is to have a menu to select certain items. When choosing a item, it should launch a script or another action. In this example i've used print("okay") as a example.
from __future__ import print_function, unicode_literals
from PyInquirer import style_from_dict, Token, prompt, Separator
from pprint import pprint
import os
style = style_from_dict({
Token.Separator: '#cc5454',
Token.QuestionMark: '#673ab7 bold',
Token.Selected: '#cc5454', # default
Token.Pointer: '#673ab7 bold',
Token.Instruction: '', # default
Token.Answer: '#f44336 bold',
Token.Question: '',
})
questions = [
{
'type': 'checkbox',
'message': 'Select a VIP build',
'name': 'F5 configuration build',
'choices': [
Separator('= VIPS ='),
{
'name': 'Nieuwe HTTP VIP'
},
{
'name': 'Nieuwe HTTPS VIP'
},
{
'name': 'Niewe VIP'
},
Separator('= Pools ='),
{
'name': 'Nieuwe Pool'
},
{
'name': 'Bestaande pool'
},
Separator('= Pool member ='),
{
'name': 'Nieuwe Pool Members'
},
{
'name': 'Bestaande Pool Members'
},
],
'validate': lambda answer: 'You must choose atleast one option.' \
if len(answer) == 0 else True
}
]
answers = prompt(questions, style=style)
pprint(answers)
if answers == ("{'F5 configuration build': ['Nieuwe HTTP VIP']}"):
print("okay")
So the
if answers == ("{'F5 configuration build': ['Nieuwe HTTP VIP']}"):
print("okay")
Should print okay after choosing the first choice, but it doesn't happend.
Any advice would be welcome!
Edit Spelling
The name should be a value that is easier to evaluate, for example only "F5" the user will not see it.
It is a type of dict data, you must access it through the index.
answers = prompt(questions, style=style)
pprint(answers)
if answers.get('F5', []) == ['Nieuwe HTTP VIP']:
print("okay")
First lines are field names. Others are values but if no corresponding data, values are filled with spaces.
In particular, bindings has no values in SHORTNAMES and APIGROUP.
pods has no value in APIGROUP
$ kubectl api-resources
NAME SHORTNAMES APIGROUP NAMESPACED KIND
bindings true Binding
pods po true Pod
deployments deploy apps true Deployment
Finally, I would like to treat output data as python dict, which key is field name.
First of all, it seems to replace spaced no value with the dummy value by regex.
NAME SHORTNAMES APIGROUP NAMESPACED KIND
bindings no-value no-value true Binding
Is it possibe?
Here is a solution with regex.
import re
data = """NAME SHORTNAMES APIGROUP NAMESPACED KIND
bindings true Binding
pods po true Pod
deployments deploy apps true Deployment"""
regex = re.compile(
"(?P<name>\S+)\s+"
"(?P<shortname>\S+)\s+"
"(?P<group>\S+)\s+"
"(?P<namespace>\S+)\s+"
"(?P<kind>\S+)"
)
header = data.splitlines()[0]
for match in regex.finditer(header):
name_index = match.start('name')
shortname_index = match.start('shortname')
group_index = match.start('group')
namespace_index = match.start('namespace')
kind_index = match.start('kind')
def get_text(line, index):
result = ''
for char in line[index:]:
if char == ' ':
break
result += char
if result:
return result
else:
return "no-value"
resources = []
for line in data.splitlines()[1:]:
resources.append({
"name" : get_text(line, name_index),
"shortname": get_text(line, shortname_index),
"group": get_text(line, group_index),
"namespace": get_text(line, namespace_index),
"kind": get_text(line, kind_index)
})
print(resources)
And the output is(formatted):
[
{
'name': 'bindings',
'shortname': 'no-value',
'group': 'no-value',
'namespace': 'true',
'kind': 'Binding'
},
{
'name': 'pods',
'shortname': 'po',
'group': 'no-value',
'namespace': 'true',
'kind': 'Pod'
},
{
'name': 'deployments',
'shortname': 'deploy',
'group': 'apps',
'namespace': 'true',
'kind': 'Deployment'
}
]
I'm trying to integrate CyberSource's REST API into a Django (Python) application. I'm following this GitHub example example.
It works like a charm but it is not clear to me from the example or from the documentation how to specify the device's fingerprint ID.
Here's a snippet of the request I'm sending in case it comes useful (note: this is just a method that lives inside a POPO):
def authorize_payment(self, card_token: str, total_amount: Money, customer: CustomerInformation = None,
merchant: MerchantInformation = None):
try:
request = {
'payment_information': {
# NOTE: REQUIRED.
'card': None,
'tokenized_card': None,
'customer': {
'customer_id': card_token,
},
},
'order_information': {
'amount_details': {
'total_amount': str(total_amount.amount),
'currency': str(total_amount.currency),
},
},
}
if customer:
request['order_information'].update({
'bill_to': {
'first_name': customer.first_name,
'last_name': customer.last_name,
'company': customer.company,
'address1': customer.address1,
'address2': customer.address2,
'locality': customer.locality,
'country': customer.country,
'email': customer.email,
'phone_number': customer.phone_number,
'administrative_area': customer.administrative_area,
'postalCode': customer.zip_code,
}
})
serialized_request = json.dumps(request)
data, status, body = self._payment_api_client.create_payment(create_payment_request=serialized_request)
return data.id
except Exception as e:
raise AuthorizePaymentError from e
I have multiple index in elastic using haystack I am trying to auto-update the index with RealtimeSignalProcessor. Is it supported by Haystack ?
Here is the link I followed .
The same thing worked for single index very well.
I suspect the Haystack_connection in settings is something wrong. please suggest the correct syntax.
I don't have any specific need to write any Custom SignalProcessors. Is there a way to use off-the-shelve Haystack Realtime - RealtimeSignalProcessor
I referred to this question but was not helpful .
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
'URL': 'http://127.0.0.1:9200/',
'INDEX_NAME': 'haystack',
'INCLUDE_SPELLING': True,
},
'Hello':
{
'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
'URL': 'http://127.0.0.1:9200/',
'INDEX_NAME': 'helloindex',
'INCLUDE_SPELLING': True,
},
'Note':
{
'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
'URL': 'http://127.0.0.1:9200/',
'INDEX_NAME': 'noteindex',
'INCLUDE_SPELLING': True,
},
}
Thank-you in advance.
Yes its possible
I was able to solve this issue by using Django-Haystack's routers
In settings.py i did this
HAYSTACK_CONNECTIONS = {
'My_Testing':
{
'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
'URL': 'http://127.0.0.1:9200/',
'INDEX_NAME': 'my_testing',
'INCLUDE_SPELLING': True,
'EXCLUDED_INDEXES': ['talks.search_indexes.NoteIndex'],
},
'Note':
{
'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
'URL': 'http://127.0.0.1:9200/',
'INDEX_NAME': 'note',
'INCLUDE_SPELLING': True,
'EXCLUDED_INDEXES': ['talks.search_indexes.My_TestingIndex'],
},
'default': {
'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
'URL': 'http://127.0.0.1:9200/',
'INDEX_NAME': 'haystack',
# 'INCLUDE_SPELLING': True,
},
}
HAYSTACK_ROUTERS = ['talks.routers.My_TestingRouter',
'talks.routers.NoteRouter']
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
and in routers.py file which is at same level as search_indexes.py add this
from haystack import routers
class My_TestingRouter(routers.BaseRouter):
def for_write(self, **hints):
return 'My_Testing'
def for_read(self, **hints):
return 'My_Testing'
class NoteRouter(routers.BaseRouter):
def for_write(self, **hints):
return 'Note'
def for_read(self, **hints):
return 'Note'
Hope this helps somebody someday.
peace.