{"id":18457164,"url":"https://github.com/redsolution/django-tinymce-attachment","last_synced_at":"2025-07-02T07:32:50.838Z","repository":{"id":978288,"uuid":"778743","full_name":"redsolution/django-tinymce-attachment","owner":"redsolution","description":"Makes attachments to objects and register them in TinyMCE","archived":false,"fork":false,"pushed_at":"2024-07-02T02:41:09.000Z","size":133,"stargazers_count":7,"open_issues_count":1,"forks_count":6,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-25T14:08:39.424Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/redsolution.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2010-07-16T12:33:46.000Z","updated_at":"2022-01-23T06:43:49.000Z","dependencies_parsed_at":"2024-11-06T08:13:45.460Z","dependency_job_id":"237ec366-cfb3-4728-a83b-bc2155444702","html_url":"https://github.com/redsolution/django-tinymce-attachment","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/redsolution/django-tinymce-attachment","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redsolution%2Fdjango-tinymce-attachment","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redsolution%2Fdjango-tinymce-attachment/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redsolution%2Fdjango-tinymce-attachment/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redsolution%2Fdjango-tinymce-attachment/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/redsolution","download_url":"https://codeload.github.com/redsolution/django-tinymce-attachment/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redsolution%2Fdjango-tinymce-attachment/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263093871,"owners_count":23412894,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T08:13:39.214Z","updated_at":"2025-07-02T07:32:50.789Z","avatar_url":"https://github.com/redsolution.png","language":"Python","readme":"\n# django tinymce attachment\n\nOpen source images management system based on the Django framework.\n\ndocumentation is not ready yet, information bellow may be incorrect\n\n## Features\n- Work with images, files and archives.\n- integration with TinyMCE editor.\n- Easy to connect to any model.\n- Resize, crop, upscale and add filters to images.\n\n## Requirements\n\n- Python 3.5\n- Django 2.2.*\n- django-tinymce 2.9.0\n- [Custom Imagekit 0.4.1 with Python 3.5 support](https://github.com/Shoker174/django-imagekit/tree/support/0.4.x)\n- django-classy-tags 0.9.0\n\n## Installation and basic usage\n\n\n1. Install package\n\n    ``git+git://github.com/shoker174/django-tinymce-attachment``\n\n2. For usage, check imagekit docs - https://django-imagekit.readthedocs.io/en/latest/#usage-overview\n\n3. Configure your settings file:\n\n\t- **ATTACHMENT_FOR_MODELS** - list of models for connecting images and files (*default: empty list*)\n\t- **ATTACHMENT_UPLOAD_DIR** - folder in the media root for storing attachment files (*default: 'upload/attachment/source'*)\n\t- **ATTACHMENT_CACHE_DIR** - folder in the media root for storing image versions (*default*: 'upload/attachment/cache')\n\t- **ATTACHMENT_IKSPECS** - file with specifications of image versions (*default*: 'attachment.ikspecs')\n\t- **ATTACHMENT_EXTRA_IMAGES, ATTACHMENT_EXTRA_FILES** - count of extra inline images/files for connected models (*default: 3*)\n\t- **ATTACHMENT_MAX_IMAGE_UPLOAD_SIZE, ATTACHMENT_MAX_FILE_UPLOAD_SIZE** - limit in bytes for uploaded images/files (*default*: None). Pay attention to Django variables: **FILE_UPLOAD_MAX_MEMORY_SIZE** and **FILE_UPLOAD_PERMISSIONS**.\n\t- **GROUP_IMAGES** - Add to attachments extra field \"group\" (*default: True*).\n\t- **ATTACHMENT_IMAGE_ROLES** - list fixed image roles - for example \"gallery\", \"caption\"(*default: False*)\n\t- **ATTACHMENT_LINK_MODELS** - list of models to be listed in link-list TinyMCE (*default: empty list*)\n\t- **ATTACHMENT_SPECS_FOR_TINYMCE** - list specifications for TinyMCE editor (*default*: empty list).\n    For example we need connect attachments to \"Page\" model.\n\n    Simple settings configuration:\n\n    ```python\n    # attachments\n    INSTALLED_APPS += ['unidecode', 'imagekit', 'attachment', '\u003cPROJECT_ROOT\u003e.custom_attachment']\n    ATTACHMENT_FOR_MODELS = [\n        #'\u003capp\u003e.\u003cmodel\u003e',\n        'pages.Page',\n    ]\n    ATTACHMENT_LINK_MODELS = [\n        #'\u003capp\u003e.\u003cmodel\u003e',\n        'pages.Page',\n    ]\n    FILE_UPLOAD_MAX_MEMORY_SIZE = '2621440'\n\tFILE_UPLOAD_PERMISSIONS = 0644\n    ATTACHMENT_EXTRA_IMAGES = 0\n\tATTACHMENT_EXTRA_FILES = 0\n    ATTACHMENT_IKSPECS = '\u003cPROJECT_ROOT\u003e.custom_attachment.ikspecs'\n\tATTACHMENT_IMAGE_ROLES = ['gallery', 'caption']\n\n\t# TinyMCE\n    INSTALLED_APPS += ['tinymce']\n    TINYMCE_DEFAULT_CONFIG = {\n    'mode': 'exact',\n    'theme': 'advanced',\n    'relative_urls': False,\n    'width': 1024,\n    'height': 300,\n    'skin': 'o2k7',\n    'plugins': 'table,advimage,advlink,inlinepopups,preview,media,searchreplace,contextmenu,paste,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras',\n    'theme_advanced_buttons1': 'justifyleft,justifycenter,justifyright,|,bold,italic,underline,strikethrough,|,sub,sup,|,bullist,numlist,|,outdent,indent,|,formatselect,removeformat,cut,copy,paste,pastetext,pasteword,|,search,replace,|,undo,redo,|,link,unlink,anchor,image,media,charmap,|,visualchars,nonbreaking',\n    'theme_advanced_buttons2': 'visualaid,tablecontrols,|,blockquote,del,ins,|preview,fullscreen,|,code',\n    'theme_advanced_toolbar_location': 'top',\n    'theme_advanced_toolbar_align': 'left',\n    'valid_elements': '*[*]',\n    'extended_valid_elements': '*[*]',\n    'custom_elements': 'noindex',\n    'external_image_list_url': 'images/',\n    'external_link_list_url': 'links/',\n    'paste_remove_styles': 'true',\n    'paste_remove_styles_if_webkit': 'true',\n    'paste_strip_class_attributes': 'all',\n    'plugin_preview_width': '900',\n    'plugin_preview_height': '800',\n    'accessibility_warnings': 'false',\n    'theme_advanced_resizing': 'true',\n    'content_style': '.mcecontentbody{font-size:14px;}',\n    }\n\n\t```\n4. Add urlpattern to main urls.py:\n\n    ```python\n    from django.views.static import serve\n\tfrom django.conf import settings\n    from django.contrib import admin\n\tfrom django.conf.urls import url, include\n\n    urlpatterns = [\n        url(r'^media/(?P\u003cpath\u003e.*)$', serve, {'document_root': settings.MEDIA_ROOT}),\n        url(r'^', include('attachment.urls')), # before admin urls\n        url(r'^admin/', admin.site.urls),\n        url(r'^tinymce/', include('tinymce.urls')),\n        # ...\n    ]\n    ```\n5. Call attachments in template:\n\n    Example №1. Get page images/files:\n    ```html\n\t{% load attachment_tags %}\n\n    {% get_images for current_page as images %}\n    {% get_files for current_page as files %}\n    ```\n\n    Example №2. Show page images/files:\n\t```\n\t{% load attachment_tags %}\n\n\t{% show_images for current_page %}\n\t{% show_files for current_page %}\n    ```\n\tTo customize attachments ``show.html`` template, stick to the following template structure:\n\t- templates/\n    \t- attachment/\n        \t- show.html\n\n    Example №3. Image specifications:\n\t```html\n    {% load attachment_tags %}\n\n    {% get_images for current_page as images %}\n    {% for image in images %}\n    \t\u003cpicture\u003e\n        \t\u003csource srcset=\"{{ image.display.url }}\" media=\"(min-width: 1216px)\"/\u003e\n            \u003csource srcset=\"{{ image.imgautox408.url }}\" media=\"(min-width: 1024px)\"/\u003e\n            \u003csource srcset=\"{{ image.img384x288.url }}\" media=\"(min-width: 768px)\"/\u003e\n         \t\u003csource srcset=\"{{ image.thumb.url }}\" media=\"(min-width: 320px)\"/\u003e\n            \u003cimg src=\"{{ image.thumb.url }}\" alt=\"{{ image.title }}\"/\u003e\n        \u003c/picture\u003e\n    {% endfor %}\n\t```\n\n6. Apply migrations, run local server and add attachments in admin\n\n    ```python\n    python manage.py migrate\n    python manage.py runserver\n    ```\n\n## Advanced usage\n\n#### Processors\n\nWe have several processors from the box:\n\n- **BottomCenterWatermark**\n- **BottomLeftWatermark**\n- **BottomRightWatermark**\n- **CenterWatermark**\n- **AroundWatermark** - repeated throughout the photo.\n- **GrayScale** - image discoloration.\n\n**Example:**\n\n1. Put ``watermark.png`` image to your images directory\n2. Create ``\u003cPROJECT_ROOT\u003e/custom_attachment/processors.py`` with the following contents:\n\n    ```python\n    from os.path import join\n    from django.conf import settings\n    from attachment.processors import BottomLeftWatermark\n\n    STATIC_PATH = join(settings.PROJECT_ROOT, 'static') if settings.DEBUG else settings.STATIC_ROOT\n\n    class BLWatermark(BottomLeftWatermark):\n\n        image_path = join(STATIC_PATH, 'img', 'watermark.png')\n        opacity = 0.7\n        left = 0\n        bottom = 50\n    ```\n3. Add Watermark processor to image specification in ``\u003cPROJECT_ROOT\u003e/custom_attachment/ikspecs.py``:\n\n    ```python\n    from imagekit.specs import ImageSpec\n    from .resizes import *\n    from .processors import BLWatermark\n    from attachment.processors import GrayScale\n\n    class WatermarkDisplay(ImageSpec):\n    \tprocessors = [ResizeDisplay, BLWatermark]\n\n    class GrayScaleDisplay(ImageSpec):\n    \tprocessors = [ResizeDisplay, GrayScale]\n    ```\n4. To add a new image specifications to the TinyMCE editor update ``settings.py``:\n\n  \t```\n    ATTACHMENT_SPECS_FOR_TINYMCE = ['watermarkdisplay', 'grayscaledisplay']\n    ```\n5. Call new image specifications in template:\n\n\t```html\n    {% load attachment_tags %}\n\n    {% get_images for current_page as images %}\n    {% for image in images %}\n        \u003cimg src=\"{{ image.watermarkdisplay.url }}\"/\u003e\n        \u003cimg src=\"{{ image.grayscaledisplay.url }}\"/\u003e\n    {% endfor %}\n\t```\n#### Commands\n\n**update_cache** - сommand updates images of specified specification or model. parameters:\n- **-s** - specify image specification, for example:\n\n\t```\n\tpython manage.py update_cache -s img384x288\n    ```\n- **-m** - specify image model *(optional, default attachment.AttachmentImage )*. For example:\n\t```\n    python manage.py update_cache -s img384x288 -m attachment.AttachmentImage\n    ```\n#### Custom application based on attachments\n\nFor example, we need the Sliders app, for use attachments backend follow next steps:\n\n**models.py**\n```python\nfrom imagekit.models import ImageModel\nfrom django.db import models\nfrom django.contrib.contenttypes.models import ContentType\nfrom django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation\nfrom attachment.fields import ImagePreviewField\nfrom attachment import settings\n\n\nclass Slide(ImageModel):\n\n    class IKOptions:\n        spec_module = settings.ATTACHMENT_IKSPECS\n        cache_dir = settings.ATTACHMENT_CACHE_DIR\n        cache_filename_format = \"%(filename)s-%(specname)s.%(extension)s\"\n        image_field = 'image'\n\n    content_type = models.ForeignKey(ContentType)\n    object_id = models.PositiveIntegerField()\n    content_object = GenericForeignKey('content_type', 'object_id')\n    image = ImagePreviewField(widget_type='horizontal', upload_to=settings.ATTACHMENT_UPLOAD_DIR)\n\n\nclass Slider(models.Model):\n\n    slides = GenericRelation(Slide)\n```\n'ImagePrviewField' has following attributes:\n- **widget_type** - set specified widget template, can take the value **horisontal**, **vertical** or None (*default: None*)\n- **upload_to** - directory to upload image","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fredsolution%2Fdjango-tinymce-attachment","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fredsolution%2Fdjango-tinymce-attachment","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fredsolution%2Fdjango-tinymce-attachment/lists"}