From d6b6f047a68b8a4ee6eccd0f54062265c6005ccf Mon Sep 17 00:00:00 2001 From: Todd Dembrey <todd.dembrey@torchbox.com> Date: Fri, 5 Jan 2018 11:21:51 +0000 Subject: [PATCH] Pull in latest changes to cookiecutter build --- .travis.yml | 13 ++++++++++++ README.md | 16 ++++++++++++++ .../navigation/migrations/0001_initial.py | 2 +- opentech/navigation/models.py | 2 +- opentech/news/migrations/0001_initial.py | 2 +- opentech/people/migrations/0001_initial.py | 2 +- .../people/admin/js/update_person_title.js | 21 +++++++++++++++++++ opentech/people/wagtail_hooks.py | 2 +- .../standardpages/migrations/0001_initial.py | 2 +- opentech/static_src/package.json | 2 +- opentech/templates/blocks/quote_block.html | 5 +++-- opentech/utils/blocks.py | 2 +- vagrant/provision.sh | 10 +++++++-- 13 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 opentech/people/static/people/admin/js/update_person_title.js diff --git a/.travis.yml b/.travis.yml index 26694aaaf..74c62d229 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,6 +35,19 @@ install: # Install project dependencies - pip install -r requirements.txt + # Install test dependencies + - pip install flake8 + + # Install node + - nvm install 8 + + # Install node dependencies + - cd ./opentech/static_src && npm install --quiet + + # Build the static files + - cd ./opentech/static_src && npm run build:prod + + # Run the tests script: # Run python code style checks diff --git a/README.md b/README.md index c7d2f35c6..df325faa3 100644 --- a/README.md +++ b/README.md @@ -34,3 +34,19 @@ djrun ``` This will make the site available on the host machine at: http://127.0.0.1:8000/ + +# Updating front-end files + +Any changes made to sass or js files will need to be recompiled using: + +``` bash +yarn build +``` + +Alternatively you can run the watcher that will rebuild on change to files: + +``` bash +yarn start +``` + +Both commands should be run from within the `opentech/static_src` folder in the vagrant box. diff --git a/opentech/navigation/migrations/0001_initial.py b/opentech/navigation/migrations/0001_initial.py index 260fefa7b..f213cf804 100644 --- a/opentech/navigation/migrations/0001_initial.py +++ b/opentech/navigation/migrations/0001_initial.py @@ -23,7 +23,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('primary_navigation', wagtail.wagtailcore.fields.StreamField((('link', wagtail.wagtailcore.blocks.StructBlock((('page', wagtail.wagtailcore.blocks.PageChooserBlock()), ('title', wagtail.wagtailcore.blocks.CharBlock(help_text="Leave blank to use the page's own title", required=False))))),), blank=True, help_text='Main site navigation')), ('secondary_navigation', wagtail.wagtailcore.fields.StreamField((('link', wagtail.wagtailcore.blocks.StructBlock((('page', wagtail.wagtailcore.blocks.PageChooserBlock()), ('title', wagtail.wagtailcore.blocks.CharBlock(help_text="Leave blank to use the page's own title", required=False))))),), blank=True, help_text='Alternative navigation')), - ('footer_navigation', wagtail.wagtailcore.fields.StreamField((('column', wagtail.wagtailcore.blocks.StructBlock((('heading', wagtail.wagtailcore.blocks.CharBlock(blank=True, help_text='Leave blank if no header required.')), ('links', wagtail.wagtailcore.blocks.ListBlock(wagtail.wagtailcore.blocks.StructBlock((('page', wagtail.wagtailcore.blocks.PageChooserBlock()), ('title', wagtail.wagtailcore.blocks.CharBlock(help_text="Leave blank to use the page's own title", required=False))))))))),), blank=True, help_text='Multiple columns of footer links with optional header.')), + ('footer_navigation', wagtail.wagtailcore.fields.StreamField((('column', wagtail.wagtailcore.blocks.StructBlock((('heading', wagtail.wagtailcore.blocks.CharBlock(required=False, help_text='Leave blank if no header required.')), ('links', wagtail.wagtailcore.blocks.ListBlock(wagtail.wagtailcore.blocks.StructBlock((('page', wagtail.wagtailcore.blocks.PageChooserBlock()), ('title', wagtail.wagtailcore.blocks.CharBlock(help_text="Leave blank to use the page's own title", required=False))))))))),), blank=True, help_text='Multiple columns of footer links with optional header.')), ('footer_links', wagtail.wagtailcore.fields.StreamField((('link', wagtail.wagtailcore.blocks.StructBlock((('page', wagtail.wagtailcore.blocks.PageChooserBlock()), ('title', wagtail.wagtailcore.blocks.CharBlock(help_text="Leave blank to use the page's own title", required=False))))),), blank=True, help_text='Single list of elements at the base of the page.')), ('site', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, to='wagtailcore.Site')), ], diff --git a/opentech/navigation/models.py b/opentech/navigation/models.py index 53d73d84a..c270b1478 100644 --- a/opentech/navigation/models.py +++ b/opentech/navigation/models.py @@ -16,7 +16,7 @@ class LinkBlock(blocks.StructBlock): class LinkColumnWithHeader(blocks.StructBlock): - heading = blocks.CharBlock(blank=True, help_text="Leave blank if no header required.") + heading = blocks.CharBlock(required=False, help_text="Leave blank if no header required.") links = blocks.ListBlock(LinkBlock()) class Meta: diff --git a/opentech/news/migrations/0001_initial.py b/opentech/news/migrations/0001_initial.py index e8a803d18..e9c99a7d7 100644 --- a/opentech/news/migrations/0001_initial.py +++ b/opentech/news/migrations/0001_initial.py @@ -55,7 +55,7 @@ class Migration(migrations.Migration): ('listing_summary', models.CharField(blank=True, help_text="The text summary used when this page appears in listings. It's also used as the description for search engines if the 'Search description' field above is not defined.", max_length=255)), ('publication_date', models.DateTimeField(blank=True, help_text='Use this field to override the date that the news item appears to have been published.', null=True)), ('introduction', models.TextField(blank=True)), - ('body', wagtail.wagtailcore.fields.StreamField((('heading', wagtail.wagtailcore.blocks.CharBlock(classname='full title', icon='title')), ('paragraph', wagtail.wagtailcore.blocks.RichTextBlock()), ('image', wagtail.wagtailcore.blocks.StructBlock((('image', wagtail.wagtailimages.blocks.ImageChooserBlock()), ('caption', wagtail.wagtailcore.blocks.CharBlock(required=False))))), ('quote', wagtail.wagtailcore.blocks.StructBlock((('quote', wagtail.wagtailcore.blocks.CharBlock(classname='title')), ('citation_link', wagtail.wagtailcore.blocks.URLBlock(required=False))))), ('embed', wagtail.wagtailembeds.blocks.EmbedBlock()), ('call_to_action', wagtail.wagtailsnippets.blocks.SnippetChooserBlock('utils.CallToActionSnippet', template='blocks/call_to_action_block.html')), ('document', wagtail.wagtailcore.blocks.StructBlock((('document', wagtail.wagtaildocs.blocks.DocumentChooserBlock()), ('title', wagtail.wagtailcore.blocks.CharBlock(required=False)))))))), + ('body', wagtail.wagtailcore.fields.StreamField((('heading', wagtail.wagtailcore.blocks.CharBlock(classname='full title', icon='title')), ('paragraph', wagtail.wagtailcore.blocks.RichTextBlock()), ('image', wagtail.wagtailcore.blocks.StructBlock((('image', wagtail.wagtailimages.blocks.ImageChooserBlock()), ('caption', wagtail.wagtailcore.blocks.CharBlock(required=False))))), ('quote', wagtail.wagtailcore.blocks.StructBlock((('quote', wagtail.wagtailcore.blocks.CharBlock(classname='title')), ('attribution', wagtail.wagtailcore.blocks.CharBlock(required=False))))), ('embed', wagtail.wagtailembeds.blocks.EmbedBlock()), ('call_to_action', wagtail.wagtailsnippets.blocks.SnippetChooserBlock('utils.CallToActionSnippet', template='blocks/call_to_action_block.html')), ('document', wagtail.wagtailcore.blocks.StructBlock((('document', wagtail.wagtaildocs.blocks.DocumentChooserBlock()), ('title', wagtail.wagtailcore.blocks.CharBlock(required=False)))))))), ('listing_image', models.ForeignKey(blank=True, help_text='Choose the image you wish to be displayed when this page appears in listings', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='images.CustomImage')), ('social_image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='images.CustomImage')), ], diff --git a/opentech/people/migrations/0001_initial.py b/opentech/people/migrations/0001_initial.py index cc6045ca5..61ae8c60b 100644 --- a/opentech/people/migrations/0001_initial.py +++ b/opentech/people/migrations/0001_initial.py @@ -55,7 +55,7 @@ class Migration(migrations.Migration): ('job_title', models.CharField(max_length=255)), ('introduction', models.TextField(blank=True)), ('website', models.URLField(blank=True, max_length=255)), - ('biography', wagtail.wagtailcore.fields.StreamField((('heading', wagtail.wagtailcore.blocks.CharBlock(classname='full title', icon='title')), ('paragraph', wagtail.wagtailcore.blocks.RichTextBlock()), ('image', wagtail.wagtailcore.blocks.StructBlock((('image', wagtail.wagtailimages.blocks.ImageChooserBlock()), ('caption', wagtail.wagtailcore.blocks.CharBlock(required=False))))), ('quote', wagtail.wagtailcore.blocks.StructBlock((('quote', wagtail.wagtailcore.blocks.CharBlock(classname='title')), ('citation_link', wagtail.wagtailcore.blocks.URLBlock(required=False))))), ('embed', wagtail.wagtailembeds.blocks.EmbedBlock()), ('call_to_action', wagtail.wagtailsnippets.blocks.SnippetChooserBlock('utils.CallToActionSnippet', template='blocks/call_to_action_block.html')), ('document', wagtail.wagtailcore.blocks.StructBlock((('document', wagtail.wagtaildocs.blocks.DocumentChooserBlock()), ('title', wagtail.wagtailcore.blocks.CharBlock(required=False)))))), blank=True)), + ('biography', wagtail.wagtailcore.fields.StreamField((('heading', wagtail.wagtailcore.blocks.CharBlock(classname='full title', icon='title')), ('paragraph', wagtail.wagtailcore.blocks.RichTextBlock()), ('image', wagtail.wagtailcore.blocks.StructBlock((('image', wagtail.wagtailimages.blocks.ImageChooserBlock()), ('caption', wagtail.wagtailcore.blocks.CharBlock(required=False))))), ('quote', wagtail.wagtailcore.blocks.StructBlock((('quote', wagtail.wagtailcore.blocks.CharBlock(classname='title')), ('attribution', wagtail.wagtailcore.blocks.CharBlock(required=False))))), ('embed', wagtail.wagtailembeds.blocks.EmbedBlock()), ('call_to_action', wagtail.wagtailsnippets.blocks.SnippetChooserBlock('utils.CallToActionSnippet', template='blocks/call_to_action_block.html')), ('document', wagtail.wagtailcore.blocks.StructBlock((('document', wagtail.wagtaildocs.blocks.DocumentChooserBlock()), ('title', wagtail.wagtailcore.blocks.CharBlock(required=False)))))), blank=True)), ('email', models.EmailField(blank=True, max_length=254)), ('mobile_phone', models.CharField(blank=True, max_length=255)), ('landline_phone', models.CharField(blank=True, max_length=255)), diff --git a/opentech/people/static/people/admin/js/update_person_title.js b/opentech/people/static/people/admin/js/update_person_title.js new file mode 100644 index 000000000..589f89eec --- /dev/null +++ b/opentech/people/static/people/admin/js/update_person_title.js @@ -0,0 +1,21 @@ +$(document).ready(function () { + var $lastNameInput = $('#id_last_name'); + var $firstNameInput = $('#id_first_name'); + var $titleInput = $('#id_title'); + var $slugInput = $('#id_slug'); + + $firstNameInput.on('input', function () {joinFirstNameLastName();}); + + $lastNameInput.on('input', function () {joinFirstNameLastName();}); + + function joinFirstNameLastName() { + var firstName = $firstNameInput.val(); + var lastName = $lastNameInput.val(); + var title = firstName + ' ' + lastName; + + $slugInput.data('previous-val', $slugInput.val()); + $titleInput.data('previous-val', $titleInput.val()); + $titleInput.val(title); + $titleInput.blur(); // Trigger slug update + } +}); diff --git a/opentech/people/wagtail_hooks.py b/opentech/people/wagtail_hooks.py index 9100b81a8..ceaff4b99 100644 --- a/opentech/people/wagtail_hooks.py +++ b/opentech/people/wagtail_hooks.py @@ -7,5 +7,5 @@ from wagtail.wagtailcore import hooks @hooks.register('insert_editor_js') def editor_js(): return mark_safe( - '<script src="%s"></script>' % static('js/update_person_title.js') + '<script src="%s"></script>' % static('people/admin/js/update_person_title.js') ) diff --git a/opentech/standardpages/migrations/0001_initial.py b/opentech/standardpages/migrations/0001_initial.py index 51278eef3..3e244f23e 100644 --- a/opentech/standardpages/migrations/0001_initial.py +++ b/opentech/standardpages/migrations/0001_initial.py @@ -48,7 +48,7 @@ class Migration(migrations.Migration): ('listing_title', models.CharField(blank=True, help_text='Override the page title used when this page appears in listings', max_length=255)), ('listing_summary', models.CharField(blank=True, help_text="The text summary used when this page appears in listings. It's also used as the description for search engines if the 'Search description' field above is not defined.", max_length=255)), ('introduction', models.TextField(blank=True)), - ('body', wagtail.wagtailcore.fields.StreamField((('heading', wagtail.wagtailcore.blocks.CharBlock(classname='full title', icon='title')), ('paragraph', wagtail.wagtailcore.blocks.RichTextBlock()), ('image', wagtail.wagtailcore.blocks.StructBlock((('image', wagtail.wagtailimages.blocks.ImageChooserBlock()), ('caption', wagtail.wagtailcore.blocks.CharBlock(required=False))))), ('quote', wagtail.wagtailcore.blocks.StructBlock((('quote', wagtail.wagtailcore.blocks.CharBlock(classname='title')), ('citation_link', wagtail.wagtailcore.blocks.URLBlock(required=False))))), ('embed', wagtail.wagtailembeds.blocks.EmbedBlock()), ('call_to_action', wagtail.wagtailsnippets.blocks.SnippetChooserBlock('utils.CallToActionSnippet', template='blocks/call_to_action_block.html')), ('document', wagtail.wagtailcore.blocks.StructBlock((('document', wagtail.wagtaildocs.blocks.DocumentChooserBlock()), ('title', wagtail.wagtailcore.blocks.CharBlock(required=False)))))))), + ('body', wagtail.wagtailcore.fields.StreamField((('heading', wagtail.wagtailcore.blocks.CharBlock(classname='full title', icon='title')), ('paragraph', wagtail.wagtailcore.blocks.RichTextBlock()), ('image', wagtail.wagtailcore.blocks.StructBlock((('image', wagtail.wagtailimages.blocks.ImageChooserBlock()), ('caption', wagtail.wagtailcore.blocks.CharBlock(required=False))))), ('quote', wagtail.wagtailcore.blocks.StructBlock((('quote', wagtail.wagtailcore.blocks.CharBlock(classname='title')), ('attribution', wagtail.wagtailcore.blocks.CharBlock(required=False))))), ('embed', wagtail.wagtailembeds.blocks.EmbedBlock()), ('call_to_action', wagtail.wagtailsnippets.blocks.SnippetChooserBlock('utils.CallToActionSnippet', template='blocks/call_to_action_block.html')), ('document', wagtail.wagtailcore.blocks.StructBlock((('document', wagtail.wagtaildocs.blocks.DocumentChooserBlock()), ('title', wagtail.wagtailcore.blocks.CharBlock(required=False)))))))), ('listing_image', models.ForeignKey(blank=True, help_text='Choose the image you wish to be displayed when this page appears in listings', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='images.CustomImage')), ('social_image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='images.CustomImage')), ], diff --git a/opentech/static_src/package.json b/opentech/static_src/package.json index 44baaff12..0e844e9bf 100755 --- a/opentech/static_src/package.json +++ b/opentech/static_src/package.json @@ -69,7 +69,7 @@ "watch": "npm-run-all -p watch:*", "//[ Syncs ]//": "", - "sync:fonts": "rsync -rtvu --delete $npm_package_config_src_font/ $npm_package_config_dest_font/", + "sync:font": "rsync -rtvu --delete $npm_package_config_src_font/ $npm_package_config_dest_font/", "sync:img": "rsync -rtvu --delete $npm_package_config_src_img/ $npm_package_config_dest_img/", "sync": "npm-run-all -p sync:*", diff --git a/opentech/templates/blocks/quote_block.html b/opentech/templates/blocks/quote_block.html index 5f95799aa..33bea5ac6 100644 --- a/opentech/templates/blocks/quote_block.html +++ b/opentech/templates/blocks/quote_block.html @@ -1,3 +1,4 @@ -<blockquote{% if value.citation_link %} cite="{{ value.citation_link }}"{% endif %}> - {{ value.quote }} +<blockquote> + <p>{{ value.quote }}</p> + {% if value.attribution %}{{ value.attribution }}{% endif %} </blockquote> diff --git a/opentech/utils/blocks.py b/opentech/utils/blocks.py index 7c97eec03..973b0372b 100644 --- a/opentech/utils/blocks.py +++ b/opentech/utils/blocks.py @@ -25,7 +25,7 @@ class DocumentBlock(blocks.StructBlock): class QuoteBlock(blocks.StructBlock): quote = blocks.CharBlock(classname="title") - citation_link = blocks.URLBlock(required=False) + attribution = blocks.CharBlock(required=False) class Meta: icon = "openquote" diff --git a/vagrant/provision.sh b/vagrant/provision.sh index 77866f4b2..4ccbdd8e3 100755 --- a/vagrant/provision.sh +++ b/vagrant/provision.sh @@ -50,7 +50,13 @@ alias djrunp="dj runserver_plus 0.0.0.0:8000" source $VIRTUALENV_DIR/bin/activate export PS1="[$PROJECT_NAME \W]\\$ " cd $PROJECT_DIR +EOF -alias djtestapply="dj test opentech.apply --keepdb; mypy ." +# Install node.js and npm +su - vagrant -c "curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -" +su - vagrant -c "sudo apt-get install -y nodejs" -EOF +# Build the static files +su - vagrant -c "sudo npm install -g yarn" +su - vagrant -c "cd $PROJECT_DIR/$DEST_DIR/$PROJECT_NAME/$PROJECT_NAME/static_src; yarn install" +su - vagrant -c "cd $PROJECT_DIR/$DEST_DIR/$PROJECT_NAME/$PROJECT_NAME/static_src; yarn build" -- GitLab