django-tinymce4-lite
django-tinymce4-lite copied to clipboard
issue Textfield shows html in production
Hi,
in development env, the text fields are formatted as expected.
But on production, the textfileds has the blank html and the menubar is not shown
Make sure you have correctly set-up static files serving in your prod environment.
static-files setup is the same for dev and prod
"There are no psychics" (c) "The Mentalist"
Obviously, something is different, but I cannot help you if you do not provide any information. Do links to the static files, especially related to TinyMCE 4, in your rendered HTML pages actually work? Are there any errors in the Django log and/or the browser console?
You're right, I'm sorry. I guess I was a too fast.
I have no errors in my logs. nothing in Django log or the browser console, and no error in sentry.
in my settings
INSTALLED_APPS = [
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize',
'widget_tweaks',
'social_django',
'accounts',
'storages',
'django.contrib.admin',
'daterange_filter',
'tinymce',
]
TINYMCE_DEFAULT_CONFIG = {
'selector': 'textarea',
'theme': 'modern',
'plugins': "table,paste,searchreplace,link ",
'toolbar1': 'bold italic underline | link | preview | ',
'contextmenu': 'formats | link ',
'menubar': False,
'inline': False,
'statusbar': True,
#'height': 600,
'width': 800,
'branding': True,
}
STATIC_URL = '/static/'
static_root_default = os.path.join(os.path.dirname(BASE_DIR), 'staticfiles')
STATIC_ROOT = config('STATIC_ROOT', default=static_root_default)
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'myproject', 'static'),
]
In my template i Includet {{ form.media }}
In my template, I import only bootstrap4 css and js
I can only repeat: make sure you have correctly set-up static files serving in your prod environment. And I'm not talking about Django. Unless you are using Whitenoise (which is a special case), Django does not serve static files in production environments. Check the configuration of your front-end server (Nginx, Apache, etc.) or cloud static storage (e.g. AWS S3) that you are using.
Hi,
I deleted tinymce4-lite complete and added new in my project.
in my .html file I tried something like this
<link rel="stylesheet" href="{% static 'tinymce/tinymce4.css' %}">
<script src="{% static 'tinymce/tinymce_init.js' %}"></script>
but its not working.
what do I have to set if the template files stored at AWS_S3?
Are you running collectstatic?
yes
-
Export Django settings module path:
export DJANGO_SETTINGS_MODULE=myproject.settings
-
Export Prod. variables:
export $(cat lib/python3.6/site-packages/myproject/confs/.env-prod | xargs)
-
Run DB migrations:
django-admin migrate --noinput
-
Run static gathering:
django-admin collectstatic --noinput
What’s the output from collectstatic?
What are your STATIC_* settings?
Are you using whitenoise to serve static files from the django app, or a more classic nginx+django combo?
Aside: export cat xargs looks weird. If .env-prod
is a dotenv-style file using bash-compatible format, sourcing would be cleaner.
ok, I start from the beginning.
settings.py
INSTALLED_APPS = [
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize',
'widget_tweaks',
'social_django',
'app1',
'app2',
'storages',
'django.contrib.admin',
'tinymce',
]
TINYMCE_DEFAULT_CONFIG = {
'selector': 'textarea',
'theme': 'modern',
'plugins': "table,paste,searchreplace,link ",
'toolbar1': 'bold italic underline | link | preview | ',
'contextmenu': 'formats | link ',
'menubar': False,
'inline': False,
'statusbar': True,
#'height': 600,
'width': 800,
'branding': True,
}
STATIC_URL = '/static/'
static_root_default = os.path.join(os.path.dirname(BASE_DIR), 'staticfiles')
STATIC_ROOT = config('STATIC_ROOT', default=static_root_default)
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'myproject', 'static'),
]
# AWS S3 configuration
AWS_STORAGE_BUCKET_NAME = 'xxx'
AWS_S3_REGION_NAME = 'eu-west-1'
AWS_ACCESS_KEY_ID = config('AWS_ACCESS_KEY_ID', default=None)
AWS_SECRET_ACCESS_KEY = config('AWS_SECRET_ACCESS_KEY', default=None)
STATICFILES_STORAGE = config(
'STATICFILES_STORAGE',
default='django.contrib.staticfiles.storage.StaticFilesStorage'
)
in my html template I have
{% extends 'base.html' %}
{% load static %}
{% block title %}Request {{ album.pk }}{% endblock %}
{% block albums_active %}active{% endblock %}
{% load humanize %}
{% block breadcrumb %}
{% endblock %}
{% block content %}
<link rel="stylesheet" href="{% static 'tinymce/tinymce4.css' %}">
<script src="{% static 'tinymce/tinymce_init.js' %}"></script>
{% csrf_token %}
{{ form.media }}
### form content ###
{% endblock %}
Then i copied tinymce/tinymce4.css and tinymce/tinymce_init.js from /home/PycharmProjects/mysite/venv/lib/python3.6/site-packages/tinymce to /home/PycharmProjects/mysite/myproject/static/tinymce
Then I upload and run on production:
- Export Django settings module path:
export DJANGO_SETTINGS_MODULE=myproject.settings
- Export Prod. variables:
export $(cat lib/python3.6/site-packages/myproject/confs/.env-prod | xargs)
- Run DB migrations:
django-admin migrate --noinput
- Run static gathering:
django-admin collectstatic --noinput
output from collectstatic: 0 static files copied to '/home/PycharmProjects/staticfiles', 461 unmodified.
When I run local or development I have the tinymce header toolbar and also html is displayed as a word document, no html brackets
But when I open on productiv, I have raw html and no tinymce header toolbar
Then i copied tinymce/tinymce4.css and tinymce/tinymce_init.js from /home/PycharmProjects/mysite/venv/lib/python3.6/site-packages/tinymce to /home/PycharmProjects/mysite/myproject/static/tinymce
Why? That’s the job of collectstatic.
But when I open on productiv, I have raw html and no tinymce header toolbar
Is the HTML generated with a link like <link rel="stylesheet" href="">
?
What’s the output of collectstatic on production?
@samazaphikel You still haven't said how you are serving your static files in production. What happens If you click links to static assets in your pages HTML code?
Also, you don't need to add TinyMCE static assets to your templates explicitly, they are added by {{ form.media }}
tag.
This I didn't notice at first.
<link rel="stylesheet" href="{% static 'tinymce/tinymce4.css' %}">
<script src="{% static 'tinymce/tinymce_init.js' %}"></script>
Then i copied tinymce/tinymce4.css and tinymce/tinymce_init.js from /home/PycharmProjects/mysite/venv/lib/python3.6/site-packages/tinymce to /home/PycharmProjects/mysite/myproject/static/tinymce
Why on earth did you do that? Those files are Django templates rendered by template engine. They are not valid JS and CSS files. The fact that they are placed in /templates
subdirectory should have given you a hint.
I am also running into this issue. I'm serving the files using Django-Storages. All static files except those from this module load as expected.
Without relevant parts of your settings it is hard to help!
Do you have tinymce in installed apps? Does the output of collectstatic look ok? Can you run findstatic tinymce/tinymce4.css ?
Do you have tinymce in installed apps?
Yes
Does the output of collectstatic look ok?
Yes
Can you run findstatic tinymce/tinymce4.css ?
It cannot be found. Judging from the file hierarchy, it seems to be notably absent.
The error seems to be caused by a request error when pulling the static files from AWS. It is perplexing that this is the case, given that all other static files load correctly. From my browser:
The issue can be resolved by linking to the CDN via the settings.py
file. The module cannot import the underlying tinymce4 js file locally (for some reason).
TINYMCE_JS_URL – a path to TinyMCE JavaScript library. Default: your_static_url/tinymce/js/tinymce/tinymce.min.js. The following example shows how to load the TinyMCE library from a CDN:
The latest V4 file can be accessed here
Can you run findstatic tinymce/tinymce4.css
Once again, this is a template, not a static asset.
Hi, I have the same issue.
My steps: in settings.py
INSTALLED_APPS = (
...
'tinymce', #the last entry in installed apps
)
TINYMCE_DEFAULT_CONFIG = {
'selector': 'textarea',
'theme': 'modern',
'plugins': 'link image preview codesample contextmenu table code lists',
'toolbar1': 'formatselect | bold italic underline | alignleft aligncenter alignright alignjustify '
'| bullist numlist | outdent indent | table | link image | codesample | preview code',
'contextmenu': 'formats | link ',
'menubar': False,
'inline': False,
'statusbar': True,
'height': 400,
'width': 400,
'branding': True,
}
in urls.py I added
url(r'^tinymce/', include('tinymce.urls')),
and in my specific html I added (in my case is named testing_form.html)
{{ form.media }}
When I run local, it looks gread, but when I publish to AWS, its not working
I use Django in combination with AWS S3 and NGINX
STATIC_URL = '/static/'
static_root_default = os.path.join(os.path.dirname(BASE_DIR), 'staticfiles')
STATIC_ROOT = config('STATIC_ROOT', default=static_root_default)
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'newproject', 'static'),
]
AWS_STORAGE_BUCKET_NAME = 'deleted for public'
AWS_S3_REGION_NAME = 'eu-west-1'
AWS_ACCESS_KEY_ID = config('AWS_ACCESS_KEY_ID', default=None)
AWS_SECRET_ACCESS_KEY = config('AWS_SECRET_ACCESS_KEY', default=None)
STATICFILES_STORAGE = config(
'STATICFILES_STORAGE',
default='django.contrib.staticfiles.storage.StaticFilesStorage'
)
Run DB migrations: django-admin migrate --noinput Run static gathering: django-admin collectstatic --noinput output from collectstatic: 0 static files copied to '/home/Projects/newproject/staticfiles', 588 unmodified.
I can open https://s3-eu-west-1.amazonaws.com/projectname/tinymce/tinymce_init.js and https://s3-eu-west-1.amazonaws.com/projectname/tinymce/tinymce4.css
from my understanding collectstatic was executed correctly because I can call the url directly
But when I open the console I get
ReferenceError: tinymce is not defined
what did I forget?
I can open https://s3-eu-west-1.amazonaws.com/projectname/tinymce/tinymce_init.js
I guess you have confused something because such URL does not exist in this project so it cannot be opened in any case.
https://s3-eu-west-1.amazonaws.com/projectname/tinymce/tinymce4.css
This is not a static CSS file but a dynamically rendered endpoint.
First of all, click Ctrl+U
to see the source of your page with TinyMCE editor. It should have the following line:
<script type="text/javascript" src="/static/tinymce/js/tinymce/tinymce.min.js"></script>
The path may be longer if you are using django-storages
with an external cloud storage like S3. Click on this path and see what happens. If you get 404, then you need to configure serving static files in your setup, be it Nginx, or S3 or whatever you are using. And such configuration is outside the scope of this project. There are plenty materials in the Internet.
Hi
I was a little bit sick, thats why no response.
When I click on the Link on published source for tinymce.min.js, I get this Error
<Error>
<Code>AccessDenied</Code>
<Message>Request has expired</Message>
<Expires>2019-05-14T11:08:55Z</Expires>
<ServerTime>2019-05-20T15:03:01Z</ServerTime>
<RequestId>910DBC899FBB74FD</RequestId>
<HostId>
rJk701fdz4If0fIUNd4LoXlE5b1pDEKptIcwyfQ/FoSBpO7XwR4iOA5q6DcdOHKpBXVSP5IuF4=
</HostId>
</Error>
I tried for all other files, and the other files are fine. Only for this one I get this Error
I can only repeat: you need to fix serving static files in your configuration. This response has nothing to do with this project or Django in general.
I think I identified the problem. django-tinymce4-lite
is rendering the URLs from S3 incorrectly. It is failing to convert the &
character to &
. I don't know if that's a Unicode issue or not, but I can see what can be done.
It's most likely this code from tinymce/widgets.py, starting at line 200
else:
html = '<textarea{0}>{1}</textarea>\n'.format(flatatt(final_attrs), escape(value))
html += '<script type="text/javascript">{0}</script>'.format(
jsmin(render_tinymce_init_js(mce_config,
mce_settings.CALLBACKS.copy(),
final_attrs['id'])
)
maybe putting the URL through a encode('ascii', 'ignore').decode('unicode_escape')
filter would solve the problem.
@fsecada01
I think I identified the problem. django-tinymce4-lite is rendering the URLs from S3 incorrectly. It is failing to convert the & character to &. I don't know if that's a Unicode issue or not, but I can see what can be done.
Could you explain what URLs you are talking about?
maybe putting the URL through a encode('ascii', 'ignore').decode('unicode_escape') filter would solve the problem.
This operation makes no sense from technical point of view. And that part of the code does not work with any URLs. It renders a textarea HTML field with the corresponding inline JS code for initializing TinyMCE widget attached to this textarea.
@romanvm
Could you explain what URLs you are talking about?
The S3 URL that gets generated when {{form.media}}
is inserted into the Django HTML template
This operation makes no sense from technical point of view. And that part of the code does not work with any URLs. It renders a textarea HTML field with the corresponding inline JS code for initializing TinyMCE widget attached to this textarea. That part of the code references the JS file required to run the HTMLField, and so references the URL location for said file when using S3.
I'm sharing with you what is most likely happening, as this is localized to JS files for this module only. No other module or collected static files are having this issue when being pulled from AWS.
The S3 URL that gets generated when {{form.media}} is inserted into the Django HTML template
OK, but the code fragment above has nothing to do with rendering {{form.media}}
tag. It is done by Django itself based on media
property of a widget class: https://github.com/romanvm/django-tinymce4-lite/blob/master/tinymce/widgets.py#L211
I'm sharing with you what is most likely happening, as this is localized to JS files for this module only.
Sorry, but I don't see you sharing any information at all. I still don't understand what exactly your problem is. If you think that this application incorrectly renders static URLs from S3, concrete examples of rendered HTML code compared to what is expected would be a good start.
OK, but the code fragment above has nothing to do with rendering
{{form.media}}
tag. It is done by Django itself based onmedia
property of a widget class: https://github.com/romanvm/django-tinymce4-lite/blob/master/tinymce/widgets.py#L211
Ah, this helps illuminate things a bit. The code snippet I shared related to how the js script address would populate the HTML head tag with the tinymce.min.js file location.
Sorry, but I don't see you sharing any information at all. I still don't understand what exactly your problem is. If you think that this application incorrectly renders static URLs from S3, concrete examples of rendered HTML code compared to what is expected would be a good start.
I'll have to roll back the fix I did for my app and share the specific addresses, but suffice to say, special characters show up in the URL addresses when they should be converted to ASCII.
Now that I'm looking at this, I think this is an issue relating to using django-tinymce4-lite
with django-storages
if you customize the location addresses for s3 files. I know I did that to split public and private files with S3 and staticfiles_storages
attempts to get the storage class from the STATICFILES_STORAGE
key.
For the greater context of what I mean: https://simpleisbetterthancomplex.com/tutorial/2017/08/01/how-to-setup-amazon-s3-in-a-django-project.html#working-with-static-and-media-assets