Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
SteinRobert committed Jan 9, 2017
0 parents commit e648af5
Show file tree
Hide file tree
Showing 28 changed files with 854 additions and 0 deletions.
166 changes: 166 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@

# Created by https://www.gitignore.io/api/osx,python,pycharm,django

### OSX ###
*.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk


### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# dotenv
.env

# virtualenv
.venv/
venv/
ENV/

# Spyder project settings
.spyderproject

# Rope project settings
.ropeproject


### PyCharm ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

.idea


## File-based project format:
*.iws

## Plugin-specific files:

# IntelliJ
/out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties

### PyCharm Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721

# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr


### Django ###
*.pyc
db.sqlite3
media

setup.cfg
.pypirc
# End of https://www.gitignore.io/api/osx,python,pycharm,django
21 changes: 21 additions & 0 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2016 Blueshoe

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
52 changes: 52 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
===================
Django-CMS Layouter
===================


**Django-CMS Layouter** is a plugin for **Django CMS** which aims to provide a grid system for authors and editors
with a high ease of use and comprehensibility. It is leveraging `Bootstrap 3 <http://getbootstrap.com/>`_ as it
is a very popular framework to create responsive websites.

Documentation
=============

Please feel free to contribute and help us to improve **Django-CMS Layouter**.

Installation and Configuration
------------------------------

**Django-CMS Layouter** supports Django-CMS>=3.4. It may way with any older version.

* Install via pip: ``pip install djangocms-layouter``.
* Add ``layouter`` to ``INSTALLED_APPS``.
* Run migrations: ``python manage.py migrate layouter``.
* Done.

Features
--------

These are the core features of **Django-CMS Layouter**:

* Flat tree in structure mode
* Automatic arrangement of columns, for different screen sizes
* Warning, due to too many plugins, in structure mode
* Toggle grid - show and hide grid in content mode


ToDo's
------

No software is perfect, everyone's code sucks. Feel free to suggest, criticize and/or contribute.

**Dynamic Warning Updates** - Dragging and Dropping in the structure view does not update the warnings within the
plugin.

**Author / Editor Documentation** - IMHO this is one of the things Django-CMS lacks. We need more and better resources
for authors and editors. Not only for Django-CMS, this plugin needs it to, for sure.

**Advanced Mode** - Not completely sure what it should look like. The current implementation is very limited
when it comes to adapting columns for different screen sizes or using more than 4 columns. It currently is completely
defined by this plugin, which can be good, but does not have to be. Some users want to plugin to take care, others want
to control the behaviour themselves.

**Tests** - There should be something like casper.js tests, maybe there is something better.
3 changes: 3 additions & 0 deletions layouter/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
__version__ = '0.1'
default_app_config = 'layouter.apps.LayouterConfig'
7 changes: 7 additions & 0 deletions layouter/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.apps import AppConfig


class LayouterConfig(AppConfig):
name = 'layouter'
32 changes: 32 additions & 0 deletions layouter/cms_plugins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
from cms.plugin_pool import plugin_pool
from django.utils.translation import ugettext_lazy as _
from cms.plugin_base import CMSPluginBase

from layouter.forms import ContainerPluginForm
from layouter.models import ContainerPlugin


class ContainerCMSPlugin(CMSPluginBase):
render_template = 'layouter/container.html'
name = _('Layouting Row')
model = ContainerPlugin
allow_children = True
form = ContainerPluginForm
change_form_template = 'layouter/change_form.html'

fieldsets = (
(None, {
'fields': ('container_type', 'margin')
}),
(_('Advanced'), {
'classes': ('collapse',),
'fields': ('css_classes',)
})
)

def render(self, context, instance, placeholder):
context['width'] = 12 - 2 * instance.margin
return super(ContainerCMSPlugin, self).render(context, instance, placeholder)

plugin_pool.register_plugin(ContainerCMSPlugin)
16 changes: 16 additions & 0 deletions layouter/cms_toolbars.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
from cms.toolbar_base import CMSToolbar
from cms.toolbar_pool import toolbar_pool
from cms.constants import RIGHT


@toolbar_pool.register
class LayouterModifier(CMSToolbar):

def populate(self):
# classes for scripting and styling
extra_classes = ['js-layouterMenu', 'layouter-menuButton']
# Button should have active state if grid is shown
if self.request.session.get('layouter_grid'):
extra_classes.append('cms-btn-active')
self.toolbar.add_button('Toggle Grid', '', side=RIGHT, extra_classes=extra_classes)
56 changes: 56 additions & 0 deletions layouter/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
from django import forms
from django.forms.widgets import RadioSelect, ChoiceInput, RadioFieldRenderer
from django.utils.encoding import force_text
from django.utils.safestring import mark_safe

from layouter.models import ContainerPlugin


class ButtonChoiceInput(ChoiceInput):
input_type = 'radio'

# This maps the column width to the corresponding css classes.
FONT_MAPPER = {
ContainerPlugin.FULL_WIDTH: u'full-width',
ContainerPlugin.THREE_QUARTER_WIDTH: u'three-quarter',
ContainerPlugin.TWO_THIRD_WIDTH: u'two-third',
ContainerPlugin.HALF_WIDTH: u'half',
ContainerPlugin.THIRD_WIDTH: u'third',
ContainerPlugin.QUARTER_WIDTH: u'quarter',
}

def __init__(self, *args, **kwargs):
super(ButtonChoiceInput, self).__init__(*args, **kwargs)
self.value = force_text(self.value)

def render(self, name=None, value=None, attrs=None):
if self.choice_value:
spans = ['<span class="icon-admin {}"></span>'.format(self.FONT_MAPPER[f])
for f in ContainerPlugin.TYPE_COLUMNS[int(self.choice_value)]]
self.choice_label = ' '.join(spans)
self.choice_label += '</br>' + str(ContainerPlugin.CONTAINER_TYPES[int(self.choice_value)][1])
self.choice_label = mark_safe(self.choice_label)
return super(ButtonChoiceInput, self).render(name, value, attrs)


class ButtonSelectRenderer(RadioFieldRenderer):
choice_input_class = ButtonChoiceInput


class ButtonSelectWidget(RadioSelect):
renderer = ButtonSelectRenderer


class ContainerPluginForm(forms.ModelForm):
class Meta:
model = ContainerPlugin
fields = ['container_type']
widgets = {
'container_type': ButtonSelectWidget
}

def clean(self):
cleaned_data = super(ContainerPluginForm, self).clean()
cleaned_data['css_classes'] = cleaned_data['css_classes'].strip()
return cleaned_data
27 changes: 27 additions & 0 deletions layouter/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('cms', '0016_auto_20160608_1535'),
]

operations = [
migrations.CreateModel(
name='ContainerPlugin',
fields=[
('cmsplugin_ptr', models.OneToOneField(parent_link=True, related_name='layouter_containerplugin', auto_created=True, primary_key=True, serialize=False, to='cms.CMSPlugin')),
('container_type', models.IntegerField(default=[100], choices=[(0, 'One tile - full width'), (1, 'Two tiles - 50 | 50'), (2, 'Two tiles - 25 | 75'), (3, 'Two tiles - 75 | 25'), (4, 'Two tiles - 33 | 66'), (5, 'Two tiles - 66 | 33'), (6, 'Three tiles - 33 | 33 | 33'), (7, 'Three tiles - 25 | 25 | 50'), (8, 'Three tiles - 25 | 50 | 25'), (9, 'Three tiles - 50 | 25 | 25'), (10, 'Four tiles - 25 | 25 | 25 | 25')])),
('margin', models.IntegerField(default=(0, 0), help_text='How much margin is needed on the left and right side?', null=True, blank=True, choices=[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)])),
('css_classes', models.CharField(max_length=512, null=True, blank=True)),
],
options={
'abstract': False,
},
bases=('cms.cmsplugin',),
),
]
Empty file added layouter/migrations/__init__.py
Empty file.
Loading

0 comments on commit e648af5

Please sign in to comment.