Open gusarg81 opened 4 years ago
Hi, nothing about this?
+1 If needed, I think I could work on and submit a PR that added this feature!
I think will be needed, just imagine different scenarios where you only need to show a few tools and others the full toolbar (at least many cases in my mind).
Lets says that as an admin of a site, in certain apps you need more tools than an user doing a comment in other public app. Just to mention an example.
Hi,
Any advance on this? Is the only thing that keeps me from upgrading (still using django-tinymce4-lite that has this feature).
Thanks.
I guess a pull request should be a start...
Yes, @claudep! I still want to work on it, but haven't been able these past days because of my work load. However I think I can work on it this week and upload a Pull Request
I worked a bit on this code these last days, and it seems you can achieve what you want by filling the mce_attrs
dictionary when initializing the widget, as described here: https://django-tinymce.readthedocs.io/en/latest/usage.html#using-the-widget
So, lets say I have one of the settings, called TINYMCE_BASIC_CONFIG (in settings.py), then I can pass that settings dict to mce_attrs like this?:
from django.conf import settings
...
content = forms.CharField(widget=TinyMCE(attrs=settings.TINYMCE_BASIC_CONFIG))
...
The attribute should be mce_attrs
, not attrs
(which is reserved for standard widget attributes).
Your TINYMCE_BASIC_CONFIG
will be merged with the default config. Is dict merging a possible issue?
The attribute should be
mce_attrs
, notattrs
(which is reserved for standard widget attributes).
Sorry, yes a bad typo.
Your
TINYMCE_BASIC_CONFIG
will be merged with the default config. Is dict merging a possible issue?
I think it will be an issue. Should not be merged, but a new one.
Your
TINYMCE_BASIC_CONFIG
will be merged with the default config. Is dict merging a possible issue?I think it will be an issue. Should not be merged, but a new one.
Then that would be a new feature. We could for example imagine a special config key like '__replace'
be set to True
so the config is replaced instead of merged.
In django-tinymce4-lite I use it like, for example in forms:
widgets = {
'text': TinyMCE(profile=settings.TINYMCE_ALT_CONFIG)
}
Just mention again in case that helps to apply something similar.
If your alternate config has the same keys as the default config, you can do the same currently with:
widgets = {
'text': TinyMCE(mce_attrs=settings.TINYMCE_ALT_CONFIG)
}
So the subject of this ticket could be to add an option to replace entirely the default config instead of merging its keys with the default.
Hi,
Sorry to insist, but there is any progress about this?
Thanks.
Didn't my comment above help you? What problem do you encounter with the current method of providing a widget mce_attrs
parameter?
Didn't my comment above help you? What problem do you encounter with the current method of providing a widget
mce_attrs
parameter?
Didn't tested yet. But this method will do a keys merge (like you said), which is not ideal.
Anyways, in the meanwhile I will test today.
As the base config doesn't have so much keys, I'm not sure it will be a problem in real cases.
Hi,
Finally I was available to test this and does not work. For example in my form:
widgets = {
'description': TinyMCE(mce_attrs=settings.TINYMCE_BASIC_CONFIG)
}
And in the frontend, it trows the error:
Uncaught TypeError: mce_conf[fn_name].includes is not a function
Now, without mce_attrs it does works.
This is my custom TINYMCE_BASIC_CONFIG:
TINYMCE_BASIC_CONFIG = {
'cleanup_on_startup': True,
'selector': 'textarea',
'plugins': '''
link image preview lists spellchecker hr textcolor colorpicker
''',
'toolbar1': 'undo redo | formatselect | bold italic underline fontsizeselect | '
'forecolor backcolor | alignleft aligncenter alignright alignjustify | '
'bullist numlist | blockquote | outdent indent | table hr | link image | '
'preview | spellchecker',
'file_browser_callback': False,
'menubar': False,
'inline': False,
'statusbar': True,
'branding': False,
'width': '100%',
'height': '250px',
'spellchecker_languages': 'Español AR=es_AR,Inglés US=en_US',
'content_css': '/static/css/base/tinymce.css',
'convert_urls': True,
'relative_urls': False,
'remove_script_host': False,
}
Is the same as the default, but with less items in the toolbar. It does works with django-tinymce4-lite.
Ok, seems the problem is file_browser_callback, removing it does work (which I saw it changed to file_picker_callback in current TinyMCE).
Now, how can I disable file_picker_callback? Which means, disabling image upload button.
Thanks.
EDIT: using 'file_picker_callback': 'null', did the trick. I don't know if is the right way.
To allow multiple TINYMCE_DEFAULT_CONFIG settings in django-tinymce and also provide an option to replace the default config entirely instead of merging its keys with the default, you can modify the TinyMCE widget's render method. Here's an example:
from django import forms
from tinymce.widgets import TinyMCE
class MyTinyMCE(TinyMCE):
def render(self, name, value, attrs=None, renderer=None):
mce_attrs = attrs.get('mce_attrs', {})
if 'configs' in mce_attrs:
configs = mce_attrs.pop('configs')
replace = mce_attrs.pop('replace', False)
if replace:
self.attrs['data-mce-config'] = configs
else:
for key, value in configs.items():
self.attrs['data-mce-' + key] = value
return super().render(name, value, attrs=attrs, renderer=renderer)
TINYMCE_CONFIGS = {
'default': {
'height': 400,
'plugins': 'advlist autolink lists link image charmap print preview anchor',
'toolbar': 'undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image',
'file_browser_callback': 'filebrowser',
},
'simple': {
'height': 200,
'plugins': 'textcolor',
'toolbar': 'undo redo | bold italic | forecolor backcolor',
'file_browser_callback': 'filebrowser',
},
}
class MyForm(forms.Form):
content = forms.CharField(widget=MyTinyMCE(mce_attrs={'configs': TINYMCE_CONFIGS['simple'], 'replace': True}))
To allow multiple TINYMCE_DEFAULT_CONFIG settings in django-tinymce, you can define a dictionary of configurations and pass it to the TinyMCE widget using the attrs argument. Here's an example:
from django import forms
from tinymce.widgets import TinyMCE
TINYMCE_CONFIGS = {
'default': {
'height': 400,
'plugins': 'advlist autolink lists link image charmap print preview anchor',
'toolbar': 'undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image',
'file_browser_callback': 'filebrowser',
},
'simple': {
'height': 200,
'plugins': 'textcolor',
'toolbar': 'undo redo | bold italic | forecolor backcolor',
'file_browser_callback': 'filebrowser',
},
}
class MyForm(forms.Form):
content = forms.CharField(widget=TinyMCE(attrs={'configs': TINYMCE_CONFIGS}))
In the above example, we define two configurations (default and simple) in a dictionary called TINYMCE_CONFIGS. We then pass this dictionary to the TinyMCE widget using the attrs argument in our form definition. The user can then select which configuration to use by setting the config attribute on the textarea element.
Unfortunately, django-tinymce does not allow for multiple TINYMCE_DEFAULT_CONFIG settings out of the box. However, you can achieve something similar by creating different tinymce widgets with different configurations, and then using these widgets in your forms.
Here's an example of how you can create two different tinymce widgets:
from django.forms.widgets import Textarea
from tinymce.widgets import TinyMCE
class CustomTinyMCE(TinyMCE):
def init(self, args, **kwargs):
custom_settings = kwargs.pop('custom_settings', {})
super().init(args, kwargs)
self.attrs.update({'data-custom-settings': json.dumps(custom_settings)})
class DefaultTinyMCE(CustomTinyMCE):
def init(self, *args, kwargs):
custom_settings = {
'theme': 'modern',
'plugins': 'link,paste,code',
}
super().init(args, custom_settings=custom_settings, **kwargs)
class AdvancedTinyMCE(CustomTinyMCE):
def init(self,args, **kwargs):
custom_settings = {
'theme': 'advanced',
'plugins': 'link,image,media,anchor,code,table,visualblocks,visualchars,fullscreen,layer',
'toolbar': 'undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image media | code | table | fullscreen | layer',
'relative_urls': False,
'remove_script_host': True,
'convert_urls': True,
}
super().init(args, custom_settings=custom_settings, kwargs)
In this example, DefaultTinyMCE and AdvancedTinyMCE inherit from a custom CustomTinyMCE widget that allows passing custom settings to the TinyMCE widget. DefaultTinyMCE uses a simple configuration with just a few plugins and features, while AdvancedTinyMCE has a more complex configuration with many plugins and features.
You can then use these widgets in your forms like so:
from django import forms
class MyForm(forms.Form):
content = forms.CharField(widget=DefaultTinyMCE())
advanced_content = forms.CharField(widget=AdvancedTinyMCE())
from tinymce.widgets import TinyMCE
from django.conf import settings
# Create the default configuration dictionary
my_default_config = {
'height': 500,
'plugins': 'advlist autolink lists link image charmap print preview anchor',
'toolbar': 'undo redo | styleselect | bold italic | alignleft aligncenter alignright | bullist numlist outdent indent | link image'
}
# Create a second configuration dictionary
my_other_config = {
'height': 400,
'plugins': 'advlist autolink lists link charmap',
'toolbar': 'undo redo | styleselect | bold italic | alignleft aligncenter alignright | bullist numlist outdent indent | link'
}
# Custom widget to use the default config
class MyTinyMCEWidget(TinyMCE):
def init(self, attrs=None, mce_attrs=None):
final_attrs = {'class': 'my_tinymce_class'}
if attrs is not None:
final_attrs.update(attrs)
if mce_attrs is None:
mce_attrs = {}
final_attrs['data-mce-config'] = json.dumps(mce_attrs)
final_attrs['data-mce-settings'] = json.dumps(my_default_config)
super().init(attrs=final_attrs)
# Custom widget to use the other config
class MyOtherTinyMCEWidget(TinyMCE):
def init(self, attrs=None, mce_attrs=None):
final_attrs = {'class': 'my_tinymce_class'}
if attrs is not None:
final_attrs.update(attrs)
if mce_attrs is None:
mce_attrs = {}
final_attrs['data-mce-config'] = json.dumps(mce_attrs)
final_attrs['data-mce-settings'] = json.dumps(my_other_config)
from django import forms
class MyForm(forms.Form):
my_field = forms.CharField(widget=MyTinyMCEWidget())
my_other_field = forms.CharField(widget=MyOtherTinyMCEWidget())
In this example, my_field will use the my_default_config settings, while my_other_field will use the my_other_config settings.
Hi,
For example, with django_tinymce_lite, I could do this in a form definition:
... widgets = { 'text': TinyMCE(profile=settings.TINYMCE_BASIC_CONFIG) } ....
So, being TINYMCE_BASIC_CONFIG an alternative config in settings.py besides TINYMCE_DEFAULT_CONFIG. How can I acchieve this in here?
Thanks in advance.