diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..dc334a2 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,30 @@ +## Description + + + +## Related resources + + + +* #... +* #... + +## Checklist + + + +* [ ] I have opened this pull request against ``master`` +* [ ] I have added or modified the tests when changing logic +* [ ] I have followed [the conventional commits guidelines](https://www.conventionalcommits.org/) to add meaningful information into the changelog +* [ ] I have read the [contribution guidelines ](https://github.com/django-cms/django-cms/blob/develop/CONTRIBUTING.rst) and I have joined #workgroup-pr-review on +[Slack](https://www.django-cms.org/slack) to find a “pr review buddy” who is going to review my pull request. diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..c436d26 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,38 @@ +name: Lint + +on: [push, pull_request] + +jobs: + flake8: + name: flake8 + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.9 + - name: Install flake8 + run: pip install --upgrade flake8 + - name: Run flake8 + uses: liskin/gh-problem-matcher-wrap@v1 + with: + linters: flake8 + run: flake8 + + isort: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.9 + - run: python -m pip install isort + - name: isort + uses: liskin/gh-problem-matcher-wrap@v1 + with: + linters: isort + run: isort -c -rc -df djangocms_attributes_field diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..1b4f675 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,40 @@ +name: CodeCov + +on: [push, pull_request] + +jobs: + unit-tests: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + python-version: [ 3.7, 3.8, 3.9, ] # latest release minus two + requirements-file: [ + dj22_cms37.txt, + dj22_cms38.txt, + dj30_cms37.txt, + dj30_cms38.txt, + dj31_cms38.txt, + ] + os: [ + ubuntu-20.04, + ] + + steps: + - uses: actions/checkout@v1 + - name: Set up Python ${{ matrix.python-version }} + + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r tests/requirements/${{ matrix.requirements-file }} + python setup.py install + + - name: Run coverage + run: coverage run setup.py test + + - name: Upload Coverage to Codecov + uses: codecov/codecov-action@v1 diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 0fce6c0..0000000 --- a/.travis.yml +++ /dev/null @@ -1,42 +0,0 @@ -language: python - -dist: xenial - -matrix: - include: - - python: 3.5 - env: TOX_ENV='flake8' - - python: 3.5 - env: TOX_ENV='isort' - # Django 2.2 - - python: 3.5 - env: DJANGO='dj22' CMS='cms37' - - python: 3.6 - env: DJANGO='dj22' CMS='cms37' - - python: 3.7 - env: DJANGO='dj22' CMS='cms37' - - python: 3.8 - env: DJANGO='dj22' CMS='cms37' - # Django 3.0, always run the lowest supported version - - python: 3.6 - env: DJANGO='dj30' CMS='cms37' - # Django 3.1, always run the lowest supported version - - python: 3.6 - env: DJANGO='dj31' CMS='cms38' - allow_failures: - - python: 3.6 - env: DJANGO='dj31' CMS='cms38' - -install: - - pip install coverage isort tox - - "if [[ $TRAVIS_PYTHON_VERSION == '3.5' ]]; then export PY_VER=py35; fi" - - "if [[ $TRAVIS_PYTHON_VERSION == '3.6' ]]; then export PY_VER=py36; fi" - - "if [[ $TRAVIS_PYTHON_VERSION == '3.7' ]]; then export PY_VER=py37; fi" - - "if [[ $TRAVIS_PYTHON_VERSION == '3.8' ]]; then export PY_VER=py38; fi" - - "if [[ ${DJANGO}z != 'z' ]]; then export TOX_ENV=$PY_VER-$DJANGO-$CMS; fi" - -script: - - tox -e $TOX_ENV - -after_success: - - bash <(curl -s https://codecov.io/bash) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 250f7ef..1269d5b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,14 @@ Changelog ========= +unreleased +========== + +2.1.0 (2022-03-27) +========== + +* Fix add / delete buttons if djangocms-admin-style is not installed + 2.0.0 (2020-09-02) ================== diff --git a/README.rst b/README.rst index f4d4263..1b8d96d 100644 --- a/README.rst +++ b/README.rst @@ -4,10 +4,10 @@ django CMS Attributes Field |pypi| |build| |coverage| -An opinionated implementation of JSONField for arbitrary HTML +This project is an opinionated implementation of JSONField for arbitrary HTML element attributes. -This project aims to provide a sensible means of storing and managing +It aims to provide a sensible means of storing and managing arbitrary HTML element attributes for later emitting them into templates. There are a wide variety of types of attributes and using the "normal" Django @@ -21,24 +21,33 @@ stored together in a single text field in the database as a JSON blob, but provides a nice widget to provide an intuitive, key/value pair interface and provide sensible validation of the keys used. + +.. note:: + + This project is considered 3rd party (no supervision by the `django CMS Association `_). Join us on `Slack `_ for more information. + + .. image:: preview.gif -Contributing -============ +******************************************* +Contribute to this project and win rewards +******************************************* + +Because this is a an open-source project, we welcome everyone to +`get involved in the project `_ and +`receive a reward `_ for their contribution. +Become part of a fantastic community and help us make django CMS the best CMS in the world. -This is a an open-source project. We'll be delighted to receive your +We'll be delighted to receive your feedback in the form of issues and pull requests. Before submitting your pull request, please review our `contribution guidelines `_. We're grateful to all contributors who have helped create and maintain this package. -Contributors are listed at the `contributors `_ +Contributors are listed at the `contributors `_ section. -One of the easiest contributions you can make is helping to translate this addon on -`Transifex `_. - Documentation ============= diff --git a/djangocms_attributes_field/__init__.py b/djangocms_attributes_field/__init__.py index afced14..a33997d 100644 --- a/djangocms_attributes_field/__init__.py +++ b/djangocms_attributes_field/__init__.py @@ -1 +1 @@ -__version__ = '2.0.0' +__version__ = '2.1.0' diff --git a/djangocms_attributes_field/fields.py b/djangocms_attributes_field/fields.py index 7364977..e0b2437 100644 --- a/djangocms_attributes_field/fields.py +++ b/djangocms_attributes_field/fields.py @@ -7,8 +7,7 @@ from django.core.validators import RegexValidator from django.db import models from django.utils.html import conditional_escape, mark_safe -from django.utils.translation import ugettext as _ -from django.utils.translation import ugettext_lazy +from django.utils.translation import gettext_lazy as _ from .widgets import AttributesWidget @@ -57,7 +56,7 @@ class AttributesField(models.Field): * The default widget is AttributesWidget from this package. """ default_error_messages = { - 'invalid': ugettext_lazy("'%s' is not a valid JSON string.") + 'invalid': _("'%s' is not a valid JSON string.") } description = "JSON object" diff --git a/djangocms_attributes_field/widgets.py b/djangocms_attributes_field/widgets.py index 7e27620..2dad209 100644 --- a/djangocms_attributes_field/widgets.py +++ b/djangocms_attributes_field/widgets.py @@ -1,7 +1,7 @@ from django.forms import Widget from django.forms.utils import flatatt from django.utils.html import escape, mark_safe, strip_spaces_between_tags -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ class AttributesWidget(Widget): @@ -13,10 +13,11 @@ class AttributesWidget(Widget): # https://www.huyng.com/posts/django-custom-form-widget-for-dictionary-and-tuple-key-value-pairs def __init__(self, *args, **kwargs): """ - Supports additional kwargs: `key_attr` and `val_attr`. + Supports additional kwargs: `key_attr`, `val_attr`, `sorted`. """ self.key_attrs = kwargs.pop('key_attrs', {}) self.val_attrs = kwargs.pop('val_attrs', {}) + self.sorted = sorted if kwargs.pop('sorted', True) else lambda x: x super().__init__(*args, **kwargs) def _render_row(self, key, value, field_name, key_attrs, val_attrs): @@ -69,7 +70,7 @@ def render(self, name, value, attrs=None, renderer=None): output = '
' if value and isinstance(value, dict) and len(value) > 0: - for key in sorted(value): + for key in self.sorted(value): output += self._render_row(key, value[key], name, flatatt(self.key_attrs), flatatt(self.val_attrs)) # Add empty template @@ -94,12 +95,16 @@ def render(self, name, value, attrs=None, renderer=None): # INSTALLED_APPS. By inlining the JS and CSS here, we avoid this. output += """