├── .nvmrc
├── tbx
├── __init__.py
├── blog
│ ├── __init__.py
│ └── migrations
│ │ ├── __init__.py
│ │ ├── 0012_remove_blogpage_marketing_only.py
│ │ ├── 0014_remove_blogpage_intro.py
│ │ ├── 0018_remove_blogpage_colour.py
│ │ ├── 0009_remove_blogindexpage_show_in_play_menu.py
│ │ ├── 0019_blogpage_body_word_count.py
│ │ ├── 0016_blogpage_related_services.py
│ │ ├── 0007_rename_related_author_to_authors.py
│ │ └── 0022_update_image_model.py
├── core
│ ├── __init__.py
│ ├── migrations
│ │ ├── __init__.py
│ │ ├── 0038_merge.py
│ │ ├── 0076_merge.py
│ │ ├── 0148_merge_20230626_1217.py
│ │ ├── 0011_auto_20150612_1126.py
│ │ ├── 0094_merge.py
│ │ ├── 0017_merge.py
│ │ ├── 0021_merge.py
│ │ ├── 0030_merge.py
│ │ ├── 0071_merge.py
│ │ ├── 0072_merge.py
│ │ ├── 0101_merge_20180830_1109.py
│ │ ├── 0097_merge_20180319_1455.py
│ │ ├── 0026_merge.py
│ │ ├── 0086_fill_filter_spec_field.py
│ │ ├── 0024_remove_reasontojoin_subtitle.py
│ │ ├── 0103_merge_20180918_1304.py
│ │ ├── 0104_merge_20180928_1009.py
│ │ ├── 0052_merge.py
│ │ ├── 0016_auto_20160205_1724.py
│ │ ├── 0110_rename_blogpagetaglist_to_tag.py
│ │ ├── 0023_merge.py
│ │ ├── 0044_aboutpage_heading.py
│ │ ├── 0117_remove_standardpage_middle_break.py
│ │ ├── 0114_remove_standardpage_show_in_play_menu.py
│ │ ├── 0126_jobindexpage_jobs_xml_feed.py
│ │ ├── 0049_auto_20160819_1421.py
│ │ ├── 0053_jobindexpage_reasons_intro.py
│ │ ├── 0062_auto_20160905_1151.py
│ │ ├── 0014_workpage_show_in_play_menu.py
│ │ ├── 0048_personpage_is_senior.py
│ │ ├── 0061_auto_20160902_1609.py
│ │ ├── 0127_jobindexpage_intro.py
│ │ ├── 0016_reasontojoin_subtitle.py
│ │ ├── 0031_blogpage_canonical_url.py
│ │ ├── 0050_auto_20160826_1123.py
│ │ ├── 0073_auto_20161026_1023.py
│ │ ├── 0056_workpage_visit_the_site.py
│ │ ├── 0095_set_blogpages_show_in_menus_true.py
│ │ ├── 0047_homepagehero_text.py
│ │ ├── 0032_jobindexpagejob_job_intro.py
│ │ ├── 0105_torchboximage_file_hash.py
│ │ ├── 0141_delete_old_image_models.py
│ │ ├── 0093_wagtail19_upgrade.py
│ │ ├── 0063_auto_20160906_0949.py
│ │ ├── 0007_auto_20150326_1142.py
│ │ ├── 0027_auto_20160603_1718.py
│ │ ├── 0085_add_filter_spec_field.py
│ │ ├── 0031_blogpage_homepage_color.py
│ │ ├── 0083_homepage_remove_unused_field.py
│ │ ├── 0027_marketinglandingpagerelatedlink_email_link.py
│ │ ├── 0065_auto_20160906_1449.py
│ │ ├── 0154_alter_socialmediasettings_site_name.py
│ │ ├── 0033_homepagehero_colour.py
│ │ ├── 0069_auto_20160915_1023.py
│ │ ├── 0058_auto_20160831_1239.py
│ │ ├── 0087_auto_20170117_1643.py
│ │ ├── 0057_auto_20160831_1135.py
│ │ ├── 0019_googleadgrantspage_to_address.py
│ │ ├── 0041_auto_20160707_1223.py
│ │ ├── 0020_auto_20160317_0955.py
│ │ ├── 0059_auto_20160831_1243.py
│ │ ├── 0081_servicespageservice_link.py
│ │ └── 0115_delete_tshirt_page.py
│ ├── templatetags
│ │ └── __init__.py
│ ├── management
│ │ └── commands
│ │ │ ├── __init__.py
│ │ │ └── test_sentry.py
│ ├── templates
│ │ └── security.txt
│ ├── apps.py
│ ├── urls.py
│ ├── utils
│ │ └── views.py
│ ├── tests.py
│ └── fields.py
├── courses
│ ├── __init__.py
│ └── migrations
│ │ └── __init__.py
├── events
│ ├── __init__.py
│ └── migrations
│ │ ├── __init__.py
│ │ └── 0002_auto_20210623_1428.py
├── images
│ ├── __init__.py
│ ├── migrations
│ │ ├── __init__.py
│ │ ├── 0003_alter_customimage_file_hash.py
│ │ └── 0005_alter_rendition_file.py
│ ├── apps.py
│ ├── factories.py
│ └── models.py
├── people
│ ├── __init__.py
│ ├── tests
│ │ └── __init__.py
│ ├── migrations
│ │ ├── __init__.py
│ │ ├── 0023_merge_20210330_1437.py
│ │ ├── 0027_merge_20210603_1719.py
│ │ ├── 0008_personpage_short_intro.py
│ │ ├── 0009_personpage_alt_short_intro.py
│ │ ├── 0018_update_contact.py
│ │ ├── 0010_contact_default_contact.py
│ │ ├── 0025_auto_20210505_1057.py
│ │ ├── 0014_contactreasonslist_is_default_not_unique.py
│ │ ├── 0011_auto_20190216_1748.py
│ │ ├── 0032_alter_contact_phone_number.py
│ │ ├── 0013_culturepage_strapline_visible.py
│ │ ├── 0022_auto_20210412_1042.py
│ │ ├── 0019_add_key_points_culture_model.py
│ │ ├── 0006_person_index_page_strapline.py
│ │ └── 0021_valuespagevalue_value_image.py
│ └── forms.py
├── work
│ ├── __init__.py
│ └── migrations
│ │ ├── __init__.py
│ │ ├── 0019_remove_workpage_descriptive_title.py
│ │ ├── 0018_workpage_client.py
│ │ ├── 0012_remove_workpage_intro.py
│ │ ├── 0011_remove_workpage_marketing_only.py
│ │ ├── 0022_workpage_date.py
│ │ ├── 0016_rename_summary_to_listing_summary.py
│ │ ├── 0031_alter_workpage_date.py
│ │ ├── 0009_remove_play_fields.py
│ │ ├── 0015_workpage_body_word_count.py
│ │ ├── 0017_listing_summary_not_required.py
│ │ ├── 0013_workpage_related_services.py
│ │ ├── 0007_rename_related_author_to_authors.py
│ │ └── 0023_date_data_migration.py
├── navigation
│ ├── __init__.py
│ ├── tests
│ │ └── __init__.py
│ ├── migrations
│ │ ├── __init__.py
│ │ ├── 0005_auto_20210802_1540.py
│ │ └── 0010_remove_navigationsettings_footer_teasers.py
│ └── templatetags
│ │ └── __init__.py
├── propositions
│ ├── __init__.py
│ ├── tests
│ │ ├── __init__.py
│ │ └── test_factories.py
│ ├── management
│ │ ├── __init__.py
│ │ └── commands
│ │ │ └── __init__.py
│ ├── migrations
│ │ ├── __init__.py
│ │ ├── 0010_merge_20230620_1607.py
│ │ ├── 0012_merge_20230808_1555.py
│ │ ├── 0018_merge_20231109_1255.py
│ │ └── 0009_alter_propositionpage_theme.py
│ └── factories.py
├── services
│ ├── __init__.py
│ ├── migrations
│ │ ├── __init__.py
│ │ ├── 0041_merge_0038_call_to_action_0040_update_services_theme.py
│ │ ├── 0013_auto_20190207_0252.py
│ │ ├── 0038_data_migration_subservice_theme.py
│ │ ├── 0021_auto_20190211_0705.py
│ │ ├── 0009_auto_20190206_2323.py
│ │ ├── 0008_servicepage_is_darktheme.py
│ │ ├── 0022_servicepage_heading_for_processes.py
│ │ ├── 0039_data_migration_service_theme.py
│ │ ├── 0023_key_points_heading_not_required.py
│ │ ├── 0030_subservicepage_remove_fields.py
│ │ ├── 0017_auto_20190207_1702.py
│ │ ├── 0018_auto_20190207_1740.py
│ │ ├── 0029_subservice_listingsettings.py
│ │ ├── 0002_auto_20190123_1133.py
│ │ └── 0003_servicepage_service.py
│ └── constants.py
├── sign_up_form
│ ├── __init__.py
│ ├── models.py
│ ├── migrations
│ │ └── __init__.py
│ └── templates
│ │ └── sign_up_form
│ │ └── includes
│ │ └── sign_up_form_page_landing.html
├── taxonomy
│ ├── __init__.py
│ ├── tests
│ │ └── __init__.py
│ ├── migrations
│ │ ├── __init__.py
│ │ ├── 0003_service_description.py
│ │ ├── 0004_service_preferred_contact.py
│ │ └── 0005_service_contact_reasons.py
│ ├── wagtail_hooks.py
│ └── admin.py
├── impact_reports
│ ├── __init__.py
│ ├── migrations
│ │ ├── __init__.py
│ │ └── 0002_alter_impactreportpage_hero_image.py
│ └── apps.py
├── project_styleguide
│ ├── __init__.py
│ ├── templatetags
│ │ ├── __init__.py
│ │ ├── wagtailimages_tags.py
│ │ ├── readingtimetags.py
│ │ ├── wagtailcore_tags.py
│ │ └── navigation_tags.py
│ ├── templates
│ │ └── patterns
│ │ │ ├── pages
│ │ │ ├── courses
│ │ │ │ ├── course_landing_page.yaml
│ │ │ │ ├── course_detail_page.yaml
│ │ │ │ └── course_landing_page.html
│ │ │ ├── errors
│ │ │ │ ├── 404.yaml
│ │ │ │ └── 404.html
│ │ │ ├── wagtail
│ │ │ │ └── password_required.yaml
│ │ │ ├── standard
│ │ │ │ ├── standard_page.yaml
│ │ │ │ └── standard_page.html
│ │ │ ├── proposition
│ │ │ │ └── sub_proposition.html
│ │ │ └── team
│ │ │ │ ├── team_detail.yaml
│ │ │ │ └── team_listing.html
│ │ │ ├── molecules
│ │ │ ├── navigation
│ │ │ │ ├── footer-top-links.yaml
│ │ │ │ ├── mobile-nav.yaml
│ │ │ │ ├── footer-links.yaml
│ │ │ │ ├── mobile-nav.html
│ │ │ │ ├── primary-nav.yaml
│ │ │ │ └── footer-links.html
│ │ │ ├── streamfield
│ │ │ │ ├── blocks
│ │ │ │ │ ├── external_story_block.yaml
│ │ │ │ │ ├── heading2_block.yaml
│ │ │ │ │ ├── heading3_block.yaml
│ │ │ │ │ ├── heading4_block.yaml
│ │ │ │ │ ├── embed_block.html
│ │ │ │ │ ├── heading2_block.html
│ │ │ │ │ ├── heading3_block.html
│ │ │ │ │ ├── heading4_block.html
│ │ │ │ │ ├── raw_html_block.html
│ │ │ │ │ ├── mailchimp_form_block.html
│ │ │ │ │ ├── testimonial_block.html
│ │ │ │ │ ├── intro_block.html
│ │ │ │ │ ├── embed_block.yaml
│ │ │ │ │ ├── paragraph_block.html
│ │ │ │ │ ├── markdown_block.html
│ │ │ │ │ ├── video_block.yaml
│ │ │ │ │ ├── wide_image_block.yaml
│ │ │ │ │ ├── mailchimp_form_block.yaml
│ │ │ │ │ ├── cta.yaml
│ │ │ │ │ ├── external_link_cta_block.yaml
│ │ │ │ │ ├── instagram-gallery.html
│ │ │ │ │ ├── external_story_block.html
│ │ │ │ │ ├── intro_block.yaml
│ │ │ │ │ ├── bustout_block.yaml
│ │ │ │ │ ├── cta.html
│ │ │ │ │ ├── paragraph_block.yaml
│ │ │ │ │ ├── thinking.html
│ │ │ │ │ ├── testimonials.html
│ │ │ │ │ ├── wide_image_block.html
│ │ │ │ │ ├── aligned_image_block.yaml
│ │ │ │ │ ├── process-section.html
│ │ │ │ │ ├── raw_html_block.yaml
│ │ │ │ │ ├── key-points.html
│ │ │ │ │ ├── impact_report_heading_block.yaml
│ │ │ │ │ ├── case_studies_section.html
│ │ │ │ │ ├── three_column_image_grid_block.yaml
│ │ │ │ │ ├── video_block.html
│ │ │ │ │ ├── paragraph_with_image_block.html
│ │ │ │ │ ├── paragraph_with_image_block.yaml
│ │ │ │ │ ├── paragraph_with_quote_block.html
│ │ │ │ │ ├── pullquote_block.yaml
│ │ │ │ │ ├── two_column_text_grid_block.html
│ │ │ │ │ ├── small_image_with_text_block.html
│ │ │ │ │ ├── three_column_image_grid_block.html
│ │ │ │ │ ├── small_image_with_text_block.yaml
│ │ │ │ │ ├── embed_plus_cta_block.yaml
│ │ │ │ │ ├── key_points_summary.html
│ │ │ │ │ ├── paragraph_with_quote_block.yaml
│ │ │ │ │ ├── markdown_block.yaml
│ │ │ │ │ ├── bustout_block.html
│ │ │ │ │ ├── external_link_cta_block.html
│ │ │ │ │ ├── key-points.yaml
│ │ │ │ │ └── impact_report_heading_block.html
│ │ │ │ ├── stream_block.yaml
│ │ │ │ ├── sub_proposition_stream_block.yaml
│ │ │ │ ├── stream_block.html
│ │ │ │ ├── streamfield-example-proposition-page
│ │ │ │ │ ├── clients-section-body.yaml
│ │ │ │ │ └── clients-section-body.html
│ │ │ │ ├── sub_proposition_stream_block.html
│ │ │ │ └── streamfield-example-team.html
│ │ │ ├── list-item
│ │ │ │ └── list-item.yaml
│ │ │ ├── hero
│ │ │ │ ├── hero--full-screen.yaml
│ │ │ │ ├── hero--service.yaml
│ │ │ │ ├── hero--full-screen.html
│ │ │ │ ├── hero.yaml
│ │ │ │ └── hero--proposition.yaml
│ │ │ ├── email-signup
│ │ │ │ ├── email-signup.yaml
│ │ │ │ └── email-signup.html
│ │ │ ├── in-page-nav
│ │ │ │ ├── in-page-nav.yaml
│ │ │ │ └── in-page-nav--service.yaml
│ │ │ ├── value
│ │ │ │ ├── value.html
│ │ │ │ └── value.yaml
│ │ │ ├── process-item
│ │ │ │ ├── process-item.yaml
│ │ │ │ └── process-item.html
│ │ │ ├── card
│ │ │ │ ├── card.yaml
│ │ │ │ └── card.html
│ │ │ ├── job-item
│ │ │ │ ├── job-item.yaml
│ │ │ │ └── job-item.html
│ │ │ ├── team-member
│ │ │ │ ├── team-member.yaml
│ │ │ │ └── team-member.html
│ │ │ ├── blog-item
│ │ │ │ └── blog-item.yaml
│ │ │ ├── event-item
│ │ │ │ └── event-item.yaml
│ │ │ ├── author
│ │ │ │ └── author.yaml
│ │ │ ├── related-item
│ │ │ │ └── related-item.yaml
│ │ │ ├── contact-slim
│ │ │ │ └── contact-slim.html
│ │ │ ├── title-block
│ │ │ │ └── title-block.yaml
│ │ │ └── help-block
│ │ │ │ └── help-block.yaml
│ │ │ ├── atoms
│ │ │ ├── badge
│ │ │ │ ├── badge.yaml
│ │ │ │ └── badge.html
│ │ │ ├── section-title
│ │ │ │ ├── section-title.yaml
│ │ │ │ └── section-title.html
│ │ │ ├── see-more
│ │ │ │ ├── see-more.yaml
│ │ │ │ └── see-more.html
│ │ │ ├── sprites
│ │ │ │ └── sprites-preview.yaml
│ │ │ ├── skip-link
│ │ │ │ └── skip-link.html
│ │ │ ├── tag
│ │ │ │ ├── tag.yaml
│ │ │ │ └── tag.html
│ │ │ ├── introduction
│ │ │ │ ├── introduction.yaml
│ │ │ │ └── introduction.html
│ │ │ ├── instagram-post
│ │ │ │ └── instagram-post.yaml
│ │ │ ├── quote-slide
│ │ │ │ ├── quote-slide.html
│ │ │ │ └── quote-slide.yaml
│ │ │ ├── menu-button
│ │ │ │ └── menu-button.html
│ │ │ └── icons
│ │ │ │ └── icon.html
│ │ │ ├── organisms
│ │ │ ├── blog-listing
│ │ │ │ └── blog-listing.html
│ │ │ ├── work-listing
│ │ │ │ └── work-listing.html
│ │ │ ├── card-listing
│ │ │ │ └── card-listing.html
│ │ │ ├── header
│ │ │ │ └── header.html
│ │ │ ├── process-block
│ │ │ │ └── process-block.html
│ │ │ └── related-content
│ │ │ │ └── related-content.html
│ │ │ └── _pattern_library_only
│ │ │ ├── streamfield
│ │ │ └── story_container.html
│ │ │ └── README.md
│ ├── apps.py
│ └── views.py
├── settings
│ ├── .gitignore
│ ├── production.py
│ ├── __init__.py
│ └── test.py
├── static_src
│ ├── sass
│ │ ├── components
│ │ │ ├── _sentinel.scss
│ │ │ ├── _raw-html-block.scss
│ │ │ ├── _related-courses.scss
│ │ │ ├── _utilities.scss
│ │ │ ├── _webstory-player.scss
│ │ │ ├── _avatar.scss
│ │ │ ├── _card-listing.scss
│ │ │ ├── _skip-link.scss
│ │ │ ├── _quote-slide.scss
│ │ │ ├── _posts-grid.scss
│ │ │ ├── _course-grid.scss
│ │ │ ├── _related-content.scss
│ │ │ ├── _filter.scss
│ │ │ ├── _header.scss
│ │ │ ├── _team.scss
│ │ │ ├── _three-col-image.scss
│ │ │ ├── _two-col-text.scss
│ │ │ ├── _small-image-with-text.scss
│ │ │ ├── _job-listing.scss
│ │ │ ├── _events.scss
│ │ │ ├── _button.scss
│ │ │ ├── _password-required.scss
│ │ │ └── _sprites-preview-icons.scss
│ │ └── abstracts
│ │ │ └── _functions.scss
│ ├── images
│ │ ├── will.jpg
│ │ ├── favicon.png
│ │ ├── firefox.png
│ │ ├── default-avatar.png
│ │ ├── help-character.png
│ │ ├── icons
│ │ │ ├── favicon.ico
│ │ │ ├── favicon-16x16.png
│ │ │ ├── favicon-32x32.png
│ │ │ ├── mstile-150x150.png
│ │ │ ├── apple-touch-icon.png
│ │ │ ├── android-chrome-192x192.png
│ │ │ ├── android-chrome-256x256.png
│ │ │ ├── browserconfig.xml
│ │ │ └── site.webmanifest
│ │ ├── default-featured.png
│ │ ├── processes-desktop.png
│ │ ├── processes-mobile.png
│ │ ├── cssBackgrounds
│ │ │ ├── 404.jpg
│ │ │ ├── frag.png
│ │ │ ├── tick.png
│ │ │ ├── diamond.svg
│ │ │ └── quote.svg
│ │ ├── sunday-times-100-best-companies.jpg
│ │ ├── shards-window.svg
│ │ ├── hero-mask.svg
│ │ ├── frag-cluster2.svg
│ │ ├── frag-cluster1.svg
│ │ └── tbx-flame.svg
│ ├── fonts
│ │ └── apercu
│ │ │ ├── apercu-black-pro.eot
│ │ │ ├── apercu-black-pro.ttf
│ │ │ ├── apercu-bold-pro.eot
│ │ │ ├── apercu-bold-pro.ttf
│ │ │ ├── apercu-bold-pro.woff
│ │ │ ├── apercu-light-pro.eot
│ │ │ ├── apercu-light-pro.ttf
│ │ │ ├── apercu-black-pro.woff
│ │ │ ├── apercu-black-pro.woff2
│ │ │ ├── apercu-bold-pro.woff2
│ │ │ ├── apercu-light-pro.woff
│ │ │ ├── apercu-light-pro.woff2
│ │ │ ├── apercu-regular-pro.eot
│ │ │ ├── apercu-regular-pro.ttf
│ │ │ ├── apercu-regular-pro.woff
│ │ │ └── apercu-regular-pro.woff2
│ └── javascript
│ │ └── components
│ │ ├── shards-images.js
│ │ ├── active-nav-item.js
│ │ └── sticky-point.js
└── wsgi.py
├── .prettierignore
├── public
└── googlebfad87a36358211e.html
├── docker
├── Procfile
├── docker-compose-frontend.yml
└── bashrc.sh
├── .env.example
├── .eslintignore
├── .flake8
├── docs
├── images
│ └── docker-diagram.png
├── page-models.md
└── index.md
├── gunicorn-conf.py
├── app.json
├── .stylelintrc.js
├── .eslintrc.js
├── heroku.yml
├── .prettierrc.toml
├── .editorconfig
├── .gitignore
├── manage.py
├── .isort.cfg
├── .babelrc.js
├── SECURITY.md
├── .git-blame-ignore-revs
├── .vscode
└── launch.json
├── browsersync.config.js
├── .dockerignore
├── .devcontainer
└── devcontainer.json
└── .github
└── pull_request_template.md
/.nvmrc:
--------------------------------------------------------------------------------
1 | 16
2 |
--------------------------------------------------------------------------------
/tbx/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/blog/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/core/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/courses/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/events/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/images/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/people/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/work/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/navigation/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/people/tests/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/propositions/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/services/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/sign_up_form/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/sign_up_form/models.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/taxonomy/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/blog/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/core/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/core/templatetags/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/events/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/images/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/impact_reports/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/navigation/tests/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/people/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/taxonomy/tests/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/work/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/courses/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/navigation/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/propositions/tests/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/services/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/settings/.gitignore:
--------------------------------------------------------------------------------
1 | /local.py
2 |
--------------------------------------------------------------------------------
/tbx/taxonomy/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/core/management/commands/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/impact_reports/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/navigation/templatetags/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/propositions/management/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/propositions/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/sign_up_form/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templatetags/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/propositions/management/commands/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | static_compiled
2 | *.html
3 | coverage
4 | venv
5 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/pages/courses/course_landing_page.yaml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/googlebfad87a36358211e.html:
--------------------------------------------------------------------------------
1 | google-site-verification: googlebfad87a36358211e.html
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/navigation/footer-top-links.yaml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docker/Procfile:
--------------------------------------------------------------------------------
1 | web: python manage.py runserver 0.0.0.0:8000
2 | frontend: npm run start
3 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/atoms/badge/badge.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | total: 9
3 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_sentinel.scss:
--------------------------------------------------------------------------------
1 | .sentinel {
2 | height: 20px;
3 | }
4 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/external_story_block.yaml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | # Uncomment this to disable running the front-end tooling in docker.
2 | # FRONTEND=local
3 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | coverage
3 | static_compiled
4 | static
5 | venv
6 | cloudflare/workers.js
7 |
--------------------------------------------------------------------------------
/.flake8:
--------------------------------------------------------------------------------
1 | [flake8]
2 | ignore = E501,F405,W503
3 | exclude = */migrations/*,node_modules/,tbx/settings/local.py
4 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/navigation/mobile-nav.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | job_count: 6
3 |
--------------------------------------------------------------------------------
/docs/images/docker-diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/docs/images/docker-diagram.png
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/atoms/section-title/section-title.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | title: Section title
3 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/atoms/see-more/see-more.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | link: '#'
3 | text: See more
4 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/atoms/sprites/sprites-preview.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | is_pattern_library: True
3 |
--------------------------------------------------------------------------------
/tbx/static_src/images/will.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/images/will.jpg
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/atoms/section-title/section-title.html:
--------------------------------------------------------------------------------
1 |
{{ title }}
2 |
--------------------------------------------------------------------------------
/tbx/static_src/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/images/favicon.png
--------------------------------------------------------------------------------
/tbx/static_src/images/firefox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/images/firefox.png
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/list-item/list-item.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | item:
3 | text: This is the text
4 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/heading2_block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value: Heading text
3 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/heading3_block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value: Heading text
3 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/heading4_block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value: Heading text
3 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/atoms/skip-link/skip-link.html:
--------------------------------------------------------------------------------
1 | Skip to main content
2 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/embed_block.html:
--------------------------------------------------------------------------------
1 | {{ value }}
2 |
--------------------------------------------------------------------------------
/tbx/static_src/images/default-avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/images/default-avatar.png
--------------------------------------------------------------------------------
/tbx/static_src/images/help-character.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/images/help-character.png
--------------------------------------------------------------------------------
/tbx/static_src/images/icons/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/images/icons/favicon.ico
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/atoms/badge/badge.html:
--------------------------------------------------------------------------------
1 | {{ total }}
2 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/atoms/tag/tag.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | item:
3 | name: tag
4 | slug: 'tag'
5 | tag_link_base: ''
6 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/heading2_block.html:
--------------------------------------------------------------------------------
1 | {{ value }}
2 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/heading3_block.html:
--------------------------------------------------------------------------------
1 | {{ value }}
2 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/heading4_block.html:
--------------------------------------------------------------------------------
1 | {{ value }}
2 |
--------------------------------------------------------------------------------
/tbx/static_src/images/default-featured.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/images/default-featured.png
--------------------------------------------------------------------------------
/tbx/static_src/images/processes-desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/images/processes-desktop.png
--------------------------------------------------------------------------------
/tbx/static_src/images/processes-mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/images/processes-mobile.png
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/atoms/introduction/introduction.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | item:
3 | introduction: This is an introduction
4 |
--------------------------------------------------------------------------------
/tbx/static_src/images/cssBackgrounds/404.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/images/cssBackgrounds/404.jpg
--------------------------------------------------------------------------------
/tbx/static_src/images/cssBackgrounds/frag.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/images/cssBackgrounds/frag.png
--------------------------------------------------------------------------------
/tbx/static_src/images/cssBackgrounds/tick.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/images/cssBackgrounds/tick.png
--------------------------------------------------------------------------------
/tbx/static_src/images/icons/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/images/icons/favicon-16x16.png
--------------------------------------------------------------------------------
/tbx/static_src/images/icons/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/images/icons/favicon-32x32.png
--------------------------------------------------------------------------------
/tbx/static_src/images/icons/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/images/icons/mstile-150x150.png
--------------------------------------------------------------------------------
/gunicorn-conf.py:
--------------------------------------------------------------------------------
1 | # Replace gunicorn's 'Server' HTTP header to avoid leaking info to attackers
2 | import gunicorn
3 |
4 | gunicorn.SERVER_SOFTWARE = ""
5 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/raw_html_block.html:
--------------------------------------------------------------------------------
1 |
2 | {{ value }}
3 |
4 |
--------------------------------------------------------------------------------
/tbx/static_src/fonts/apercu/apercu-black-pro.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/fonts/apercu/apercu-black-pro.eot
--------------------------------------------------------------------------------
/tbx/static_src/fonts/apercu/apercu-black-pro.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/fonts/apercu/apercu-black-pro.ttf
--------------------------------------------------------------------------------
/tbx/static_src/fonts/apercu/apercu-bold-pro.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/fonts/apercu/apercu-bold-pro.eot
--------------------------------------------------------------------------------
/tbx/static_src/fonts/apercu/apercu-bold-pro.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/fonts/apercu/apercu-bold-pro.ttf
--------------------------------------------------------------------------------
/tbx/static_src/fonts/apercu/apercu-bold-pro.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/fonts/apercu/apercu-bold-pro.woff
--------------------------------------------------------------------------------
/tbx/static_src/fonts/apercu/apercu-light-pro.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/fonts/apercu/apercu-light-pro.eot
--------------------------------------------------------------------------------
/tbx/static_src/fonts/apercu/apercu-light-pro.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/fonts/apercu/apercu-light-pro.ttf
--------------------------------------------------------------------------------
/tbx/static_src/images/icons/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/images/icons/apple-touch-icon.png
--------------------------------------------------------------------------------
/tbx/core/templates/security.txt:
--------------------------------------------------------------------------------
1 | Contact: mailto:security@torchbox.com
2 | Canonical: {{ security_txt }}
3 | Expires: {{ expires }}
4 | Preferred-Languages: en
5 |
--------------------------------------------------------------------------------
/tbx/static_src/fonts/apercu/apercu-black-pro.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/fonts/apercu/apercu-black-pro.woff
--------------------------------------------------------------------------------
/tbx/static_src/fonts/apercu/apercu-black-pro.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/fonts/apercu/apercu-black-pro.woff2
--------------------------------------------------------------------------------
/tbx/static_src/fonts/apercu/apercu-bold-pro.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/fonts/apercu/apercu-bold-pro.woff2
--------------------------------------------------------------------------------
/tbx/static_src/fonts/apercu/apercu-light-pro.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/fonts/apercu/apercu-light-pro.woff
--------------------------------------------------------------------------------
/tbx/static_src/fonts/apercu/apercu-light-pro.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/fonts/apercu/apercu-light-pro.woff2
--------------------------------------------------------------------------------
/tbx/static_src/fonts/apercu/apercu-regular-pro.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/fonts/apercu/apercu-regular-pro.eot
--------------------------------------------------------------------------------
/tbx/static_src/fonts/apercu/apercu-regular-pro.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/fonts/apercu/apercu-regular-pro.ttf
--------------------------------------------------------------------------------
/tbx/static_src/fonts/apercu/apercu-regular-pro.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/fonts/apercu/apercu-regular-pro.woff
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "scripts": {
3 | "dokku": {
4 | "postdeploy": "django-admin createcachetable && django-admin migrate --noinput"
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class ProjectStyleguideConfig(AppConfig):
5 | name = "tbx.project_styleguide"
6 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/mailchimp_form_block.html:
--------------------------------------------------------------------------------
1 |
2 | {{ value }}
3 |
4 |
--------------------------------------------------------------------------------
/tbx/static_src/fonts/apercu/apercu-regular-pro.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/fonts/apercu/apercu-regular-pro.woff2
--------------------------------------------------------------------------------
/.stylelintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | // See https://github.com/torchbox/stylelint-config-torchbox for rules.
3 | extends: 'stylelint-config-torchbox',
4 | };
5 |
--------------------------------------------------------------------------------
/tbx/static_src/images/icons/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/images/icons/android-chrome-192x192.png
--------------------------------------------------------------------------------
/tbx/static_src/images/icons/android-chrome-256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/images/icons/android-chrome-256x256.png
--------------------------------------------------------------------------------
/tbx/static_src/images/sunday-times-100-best-companies.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/wagtail-torchbox/HEAD/tbx/static_src/images/sunday-times-100-best-companies.jpg
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/testimonial_block.html:
--------------------------------------------------------------------------------
1 | {% include "patterns/molecules/quote-slider/quote-slider.html" with items=value %}
2 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_raw-html-block.scss:
--------------------------------------------------------------------------------
1 | .raw-html-block {
2 | border: 10px solid var(--color--light-grey);
3 | max-width: 550px;
4 | margin: 0 auto;
5 | }
6 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_related-courses.scss:
--------------------------------------------------------------------------------
1 | .related-courses {
2 | @include media-query(x-large) {
3 | margin-left: $variable-gutter--medium;
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | // See https://github.com/torchbox/eslint-config-torchbox for rules.
3 | extends: 'torchbox',
4 | parser: '@babel/eslint-parser',
5 | };
6 |
--------------------------------------------------------------------------------
/tbx/images/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class ImagesConfig(AppConfig):
5 | default_auto_field = "django.db.models.AutoField"
6 | name = "tbx.images"
7 |
--------------------------------------------------------------------------------
/tbx/impact_reports/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class ImpactReportsConfig(AppConfig):
5 | name = "tbx.impact_reports"
6 | label = "impact_reports"
7 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_utilities.scss:
--------------------------------------------------------------------------------
1 | .u {
2 | &--pb-0 {
3 | padding-bottom: 0;
4 | }
5 | }
6 |
7 | .u-sr-only {
8 | @include hidden();
9 | }
10 |
--------------------------------------------------------------------------------
/tbx/taxonomy/wagtail_hooks.py:
--------------------------------------------------------------------------------
1 | from wagtail.snippets.models import register_snippet
2 |
3 | from .admin import TaxonomyModelAdminGroup
4 |
5 | register_snippet(TaxonomyModelAdminGroup)
6 |
--------------------------------------------------------------------------------
/tbx/core/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class TorchboxCoreAppConfig(AppConfig):
5 | name = "tbx.core"
6 | label = "torchbox"
7 | verbose_name = "Torchbox"
8 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/intro_block.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags %}
2 |
3 | {{ value|richtext }}
4 |
5 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/hero/hero--full-screen.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | background_url: 'https://media.torchbox.com/images/kitchen.width-1920.jpg'
3 | background_color: '#fd5765'
4 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/embed_block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value: VIDEO
3 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/paragraph_block.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags %}
2 |
3 | {{ value|richtext }}
4 |
5 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/pages/errors/404.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | settings:
3 | utils:
4 | SystemMessagesSettings:
5 | title_404: Err...
6 | body_404: Take me home
7 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/email-signup/email-signup.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | label: Sign up for news, events and digital insights
3 | placeholder: name@email.com
4 | action: Sign up
5 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/markdown_block.html:
--------------------------------------------------------------------------------
1 | {% load wagtailmarkdown %}
2 |
3 | {{ value|markdown }}
4 |
5 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/organisms/blog-listing/blog-listing.html:
--------------------------------------------------------------------------------
1 | {% for post in blog_posts %}
2 | {% include "patterns/molecules/blog-item/blog-item.html" with item=post %}
3 | {% endfor %}
4 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/organisms/work-listing/work-listing.html:
--------------------------------------------------------------------------------
1 | {% for work in works %}
2 | {% include "patterns/molecules/related-item/related-item.html" with item=work %}
3 | {% endfor %}
4 |
--------------------------------------------------------------------------------
/tbx/images/factories.py:
--------------------------------------------------------------------------------
1 | from tbx.images.models import CustomImage
2 | from wagtail_factories import ImageFactory
3 |
4 |
5 | class CustomImageFactory(ImageFactory):
6 | class Meta:
7 | model = CustomImage
8 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/in-page-nav/in-page-nav.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | title: Design + build products
3 | section_titles:
4 | - Services
5 | - About support
6 | - Clients
7 | - Blog
8 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/atoms/instagram-post/instagram-post.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | embed:
3 | url: https://example.com
4 | author_name: torchboxltd
5 | thumbnail_url: https://placekitten.com/480/360
6 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templatetags/wagtailimages_tags.py:
--------------------------------------------------------------------------------
1 | from pattern_library.monkey_utils import override_tag
2 | from wagtail.images.templatetags.wagtailimages_tags import register
3 |
4 | override_tag(register, name="image")
5 |
--------------------------------------------------------------------------------
/heroku.yml:
--------------------------------------------------------------------------------
1 | build:
2 | docker:
3 | web:
4 | dockerfile: Dockerfile
5 | target: production
6 | release:
7 | image: web
8 | command:
9 | - django-admin createcachetable && django-admin migrate --noinput
10 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templatetags/readingtimetags.py:
--------------------------------------------------------------------------------
1 | from pattern_library.monkey_utils import override_tag
2 | from tbx.core.templatetags.reading_time_tags import register
3 |
4 | override_tag(register, name="get_reading_time_minutes")
5 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/hero/hero--service.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | title: Example title
3 | desc: Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.
4 |
--------------------------------------------------------------------------------
/tbx/sign_up_form/templates/sign_up_form/includes/sign_up_form_page_landing.html:
--------------------------------------------------------------------------------
1 | {% load wagtailimages_tags %}
2 |
3 | {% image page.call_to_action_image original %}
4 |
5 |
6 | {{ page.thank_you_text }}
7 |
8 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_webstory-player.scss:
--------------------------------------------------------------------------------
1 | /* stylelint-disable selector-type-no-unknown */
2 | amp-story-player {
3 | @include streamblock-padding();
4 | display: block;
5 | min-width: 300px;
6 | height: 622px;
7 | }
8 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/video_block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value:
3 | autoplay: true
4 | video:
5 | type: video
6 | file_extension: mp4
7 | url: https://placehold.co/1024x576.mp4
8 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/atoms/quote-slide/quote-slide.html:
--------------------------------------------------------------------------------
1 |
2 | {% include "patterns/molecules/streamfield/blocks/pullquote_block.html" with value=item classes="pullquote--slider" %}
3 |
4 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/wide_image_block.yaml:
--------------------------------------------------------------------------------
1 | tags:
2 | image:
3 | value.image fill-1600x900 as wide_image:
4 | target_var: wide_image
5 | raw:
6 | url: '//placekitten.com/1600/900'
7 |
--------------------------------------------------------------------------------
/.prettierrc.toml:
--------------------------------------------------------------------------------
1 | # See https://prettier.io/docs/en/options.html.
2 | # Prettier also reads .editorconfig.
3 | printWidth = 80
4 | singleQuote = true
5 | quoteProps = 'consistent'
6 | trailingComma = 'all'
7 | arrowParens = 'always'
8 | proseWrap = 'preserve'
9 |
--------------------------------------------------------------------------------
/docker/docker-compose-frontend.yml:
--------------------------------------------------------------------------------
1 | # A custom compose file for $FRONTEND=docker, which also binds frontend ports
2 |
3 | version: '3.7' # NB synchronise with /docker-compose.yml
4 | services:
5 | web:
6 | ports:
7 | - 3000:3000 # browser-sync
8 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/mailchimp_form_block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value: '
'
3 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/stream_block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value:
3 | - dummy
4 |
5 | tags:
6 | include_block:
7 | block:
8 | template_name: 'patterns/_pattern_library_only/streamfield/story_container.html'
9 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/cta.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value:
3 | text: 'Work with the best in the business'
4 | link:
5 | 0:
6 | value:
7 | text: Meet the team
8 | url: '#'
9 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/external_link_cta_block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value:
3 | link_url: '#'
4 | heading: Check upcoming course dates and apply
5 | text: If the dates don’t work, we can notify you of future courses
6 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/instagram-gallery.html:
--------------------------------------------------------------------------------
1 |
2 | {% for post in value.items %}
3 | {% include "patterns/atoms/instagram-post/instagram-post.html" %}
4 | {% endfor %}
5 |
6 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/pages/wagtail/password_required.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | form:
3 | password: | # pragma: allowlist secret
4 | Password
5 |
6 |
--------------------------------------------------------------------------------
/tbx/static_src/images/shards-window.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/in-page-nav/in-page-nav--service.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | title: Design + build products
3 | item:
4 | - { title: title, href: navitem1 }
5 | - { title: title, href: navitem2 }
6 | - { title: title, href: navitem3 }
7 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/sub_proposition_stream_block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value:
3 | - dummy
4 |
5 | tags:
6 | include_block:
7 | block:
8 | template_name: 'patterns/_pattern_library_only/streamfield/story_container.html'
9 |
--------------------------------------------------------------------------------
/tbx/settings/production.py:
--------------------------------------------------------------------------------
1 | from .base import * # noqa
2 |
3 | # Disable debug mode
4 | DEBUG = False
5 |
6 |
7 | # Facebook JSSDB app id
8 | FB_APP_ID = "323944607389"
9 |
10 |
11 | try:
12 | from .local import * # noqa
13 | except ImportError:
14 | pass
15 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/atoms/menu-button/menu-button.html:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/tbx/static_src/images/cssBackgrounds/diamond.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 4
6 | charset = utf-8
7 | trim_trailing_whitespace = true
8 | insert_final_newline = true
9 |
10 | [*.md]
11 | trim_trailing_whitespace = false
12 |
13 | [*.{yaml,yml,json,md}]
14 | indent_size = 2
15 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_avatar.scss:
--------------------------------------------------------------------------------
1 | .avatar {
2 | height: 100px;
3 | width: 100px;
4 | min-width: 100px;
5 | border-radius: 90px;
6 |
7 | &__image {
8 | height: 100%;
9 | min-width: 100%;
10 | border-radius: 100%;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/external_story_block.html:
--------------------------------------------------------------------------------
1 | {% load static %}
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/organisms/card-listing/card-listing.html:
--------------------------------------------------------------------------------
1 |
2 | {% for card_item in card_items %}
3 | {% include "patterns/molecules/card/card.html" with item=card_item %}
4 | {% endfor %}
5 |
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | .DS_Store
3 | *.swp
4 | /venv/
5 | /.venv/
6 | .env
7 | .python-version
8 | /static/
9 | static_compiled/
10 | /media/
11 | /media.old/
12 | /tmp/
13 | /docs/_build/
14 | .idea/
15 | node_modules*
16 | /None
17 | *.log
18 | /.vscode/*
19 | !/.vscode/launch.json
20 | /database_dumps/
21 |
--------------------------------------------------------------------------------
/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import os
3 | import sys
4 |
5 | if __name__ == "__main__":
6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tbx.settings.production")
7 |
8 | from django.core.management import execute_from_command_line
9 |
10 | execute_from_command_line(sys.argv)
11 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/stream_block.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags %}
2 |
3 | {% if value %}
4 |
5 | {% for block in value %}
6 | {% include_block block %}
7 | {% endfor %}
8 |
9 | {% endif %}
10 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/streamfield-example-proposition-page/clients-section-body.yaml:
--------------------------------------------------------------------------------
1 | tags:
2 | image:
3 | client.image width-400 class="client-item__image" loading="lazy" alt="":
4 | raw: ' '
5 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templatetags/wagtailcore_tags.py:
--------------------------------------------------------------------------------
1 | from pattern_library.monkey_utils import override_tag
2 | from wagtail.templatetags.wagtailcore_tags import register
3 |
4 | override_tag(register, name="include_block")
5 | override_tag(register, name="pageurl")
6 | override_tag(register, name="slugurl")
7 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/atoms/introduction/introduction.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags %}
2 |
3 |
4 |
5 | {{ introduction|richtext }}
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/atoms/quote-slide/quote-slide.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | item:
3 | quote: Thank you for your amazing and continued partnership Torchbox - our new website exceeds expectations!
4 | name: Sarah Toms
5 | role: Executive Director, Wharton Interactive at The Wharton School
6 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templatetags/navigation_tags.py:
--------------------------------------------------------------------------------
1 | from pattern_library.monkey_utils import override_tag
2 | from tbx.navigation.templatetags.navigation_tags import register
3 |
4 | override_tag(register, name="primarynav")
5 | override_tag(register, name="sidebar")
6 | override_tag(register, name="footerlinks")
7 |
--------------------------------------------------------------------------------
/tbx/static_src/images/hero-mask.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.isort.cfg:
--------------------------------------------------------------------------------
1 | [settings]
2 | default_section=FIRSTPARTY
3 | force_grid_wrap=0
4 | include_trailing_comma=True
5 | known_django=django
6 | known_first_party=tbx
7 | multi_line_output=3
8 | sections=FUTURE,STDLIB,DJANGO,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
9 | skip=migrations,node_modules,venv,.venv,.git
10 | use_parentheses=True
11 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/pages/standard/standard_page.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | page:
3 | title: Your Data, Privacy & Cookies
4 | get_verbose_name: standard
5 |
6 | tags:
7 | include_block:
8 | page.body:
9 | template_name: 'patterns/molecules/streamfield/streamfield-example-standard.html'
10 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_card-listing.scss:
--------------------------------------------------------------------------------
1 | .card-listing {
2 | display: grid;
3 | grid-template-columns: 1fr;
4 | grid-column-gap: 10px;
5 | grid-row-gap: 10px;
6 | margin-bottom: ($gutter * 4);
7 |
8 | @include media-query(medium) {
9 | grid-template-columns: 1fr;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/intro_block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Proin sagittis nisl rhoncus mattis. Augue eget arcu dictum varius duis at consectetur lorem donec.
'
3 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_skip-link.scss:
--------------------------------------------------------------------------------
1 | .skip-link {
2 | @include z-index(skip-link);
3 | position: absolute;
4 | top: -200px;
5 | left: 0;
6 | color: var(--color--black);
7 | background-color: var(--color--white);
8 | padding: $grid;
9 |
10 | &:focus {
11 | top: 0;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/bustout_block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value:
3 | text: sample bustout block text
4 |
5 | tags:
6 | image:
7 | value.image fill-1500x1200 as bustout_image:
8 | target_var: bustout_image
9 | raw:
10 | url: '//placekitten.com/1500/1200'
11 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/cta.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags %}
2 |
3 |
{{ value.text|richtext }}
4 | {% with link=value.link.0.value %}
5 |
{{ link.text }}
6 | {% endwith %}
7 |
8 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/paragraph_block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Proin sagittis nisl rhoncus mattis. Augue eget arcu dictum varius duis at consectetur lorem donec.
'
3 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/atoms/tag/tag.html:
--------------------------------------------------------------------------------
1 | {% if has_all_filter %}All{% else %}{{ item.name }}{% endif %}
6 |
7 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/thinking.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags %}
2 |
3 | {% include "patterns/organisms/latest-posts/latest-posts.html" with blogs_section_title=value.title classes="service-section" feature_first=True data_attrs="data-service-section" filter_by=page.filter_by hide_title=hide_title %}
4 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/value/value.html:
--------------------------------------------------------------------------------
1 | {% load wagtailimages_tags wagtailcore_tags %}
2 |
3 |
4 | {% image item.value_image fill-840x400 class="value__image" %}
5 |
{{ item.heading }}
6 |
{{ item.text|richtext }}
7 |
8 |
--------------------------------------------------------------------------------
/tbx/static_src/images/icons/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #fd5765
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_quote-slide.scss:
--------------------------------------------------------------------------------
1 | .quote-slide {
2 | opacity: 0;
3 | transition: opacity 0.2s ease-in;
4 |
5 | &.glide__slide--active {
6 | opacity: 1;
7 | }
8 |
9 | .streamfield & {
10 | &::before {
11 | content: none; // don't show li arrow
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/tbx/services/constants.py:
--------------------------------------------------------------------------------
1 | # These suffixes are used in the
2 | # sub service to sub proposition page migration.
3 | # See:
4 | # - tbx/propositions/management/commands/migrate_subservicepages.py
5 | # - tbx/propositions/management/commands/undo_subservicepage_migration.py
6 | DEPRECATED_TITLE_SUFFIX = "(NO LONGER IN USE)"
7 | DEPRECATED_SLUG_SUFFIX = "--deprecated"
8 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/testimonials.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags %}
2 |
3 | {% include "patterns/molecules/streamfield/blocks/client-logo-block.html" with title=value.title value=value.client_logos quotes=value.testimonials %}
4 |
5 |
--------------------------------------------------------------------------------
/tbx/core/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from tbx.blog.feeds import BlogFeed
4 | from tbx.core import views
5 |
6 | urlpatterns = [
7 | path("blog/feed/", BlogFeed(), name="blog_feed"),
8 | path("newsletter-subscribe", views.newsletter_subsribe),
9 | path(".well-known/security.txt", views.SecurityView.as_view(), name="security-txt"),
10 | ]
11 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/process-item/process-item.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | item:
3 | title: Digital Marketing Account Manager
4 | description: Plan and implement multi-channel digital marketing campaigns, while growing our relationships with some of the very biggest charities and NGO’s.
5 | tags:
6 | pageurl:
7 | page:
8 | raw: '#'
9 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_posts-grid.scss:
--------------------------------------------------------------------------------
1 | .posts-grid {
2 | padding: 60px 0 0;
3 |
4 | @include media-query(medium) {
5 | padding: 100px 0 0;
6 | }
7 |
8 | @include media-query(large) {
9 | display: grid;
10 | grid-template-columns: 1fr 1fr 1fr;
11 | padding: 100px 0;
12 | grid-gap: 20px;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0038_merge.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-07-06 13:41
3 |
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0037_auto_20160701_1307"),
12 | ("torchbox", "0030_merge"),
13 | ]
14 |
15 | operations = []
16 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0076_merge.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-11-24 09:29
3 |
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0072_merge"),
12 | ("torchbox", "0075_auto_20161124_0845"),
13 | ]
14 |
15 | operations = []
16 |
--------------------------------------------------------------------------------
/tbx/people/migrations/0023_merge_20210330_1437.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.17 on 2021-03-30 13:37
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("people", "0022_auto_20210326_1202"),
10 | ("people", "0022_culturepage_featured_blogs"),
11 | ]
12 |
13 | operations = []
14 |
--------------------------------------------------------------------------------
/tbx/people/migrations/0027_merge_20210603_1719.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.17 on 2021-06-03 16:19
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("people", "0026_culturepage_instagram_posts"),
10 | ("people", "0024_auto_20210412_1428"),
11 | ]
12 |
13 | operations = []
14 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/card/card.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | item:
3 | title: Neque porro quisquam est qui dolorem ipsum quia dolor sit amet
4 | description: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas ut finibus massa. Vivamus consequat est ut elit interdum condimentum.
5 | tags:
6 | pageurl:
7 | item.link:
8 | raw: '#'
9 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/wide_image_block.html:
--------------------------------------------------------------------------------
1 | {% load wagtailimages_tags %}
2 |
3 |
4 | {% image value.image max-1600x900 as wide_image %}
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.babelrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | [
4 | '@babel/preset-env',
5 | {
6 | modules: false,
7 | },
8 | ],
9 | '@babel/preset-react',
10 | ],
11 | env: {
12 | test: {
13 | presets: ['@babel/preset-env', '@babel/preset-react'],
14 | },
15 | },
16 | };
17 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0148_merge_20230626_1217.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.18 on 2023-06-26 11:17
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 | dependencies = [
8 | ("torchbox", "0147_call_to_action"),
9 | ("torchbox", "0147_cleanup_old_database_schema_and_tables"),
10 | ]
11 |
12 | operations = []
13 |
--------------------------------------------------------------------------------
/tbx/core/utils/views.py:
--------------------------------------------------------------------------------
1 | from django.views import defaults
2 |
3 |
4 | def page_not_found(request, exception, template_name="patterns/pages/errors/404.html"):
5 | return defaults.page_not_found(request, exception, template_name)
6 |
7 |
8 | def server_error(request, template_name="patterns/pages/errors/500.html"):
9 | return defaults.server_error(request, template_name)
10 |
--------------------------------------------------------------------------------
/tbx/events/migrations/0002_auto_20210623_1428.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.24 on 2021-06-23 13:28
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("events", "0001_initial"),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterModelOptions(name="event", options={},),
14 | ]
15 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/aligned_image_block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value:
3 | alignment: full
4 | caption: Some caption
5 | attribution: Some attribution
6 |
7 | tags:
8 | image:
9 | value.image fill-730x490 as aligned_image:
10 | raw: |
11 |
12 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security
2 |
3 | If you find a security issue in our website, please email us so we can work together to find and patch the issue. We appreciate responsible disclosure with any security related issues, so please contact us first before creating a GitHub issue.
4 |
5 | Up-to-date contact information can be found in our `security.txt`: https://torchbox.com/.well-known/security.txt.
6 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0011_auto_20150612_1126.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 |
4 | from django.db import models, migrations
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ("torchbox", "0010_auto_20150611_1528"),
11 | ]
12 |
13 | operations = [
14 | migrations.AlterModelOptions(name="workpage", options={},),
15 | ]
16 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0094_merge.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2017-09-20 11:01
3 |
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0093_auto_20170315_1306"),
12 | ("torchbox", "0093_wagtail19_upgrade"),
13 | ]
14 |
15 | operations = []
16 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/job-item/job-item.yaml:
--------------------------------------------------------------------------------
1 | content:
2 | item:
3 | title: Digital Marketing Account Manager
4 | description: Plan and implement multi-channel digital marketing campaigns, while growing our relationships with some of the very biggest charities and NGO’s.
5 | department: Digital Marketing
6 | location: Bristol, Charlbury and remote
7 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/process-section.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags %}
2 |
3 | {% include "patterns/organisms/process-block/process-block.html" with processes=value.processes section_title=value.title section_cta=value.process_section_cta %}
4 |
5 |
--------------------------------------------------------------------------------
/tbx/propositions/migrations/0010_merge_20230620_1607.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.18 on 2023-06-20 15:07
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 | dependencies = [
8 | ("propositions", "0009_auto_20230503_1527"),
9 | ("propositions", "0009_alter_propositionpage_theme"),
10 | ]
11 |
12 | operations = []
13 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0017_merge.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-02-22 10:29
3 |
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0016_auto_20160205_1724"),
12 | ("torchbox", "0015_auto_20160218_1201"),
13 | ]
14 |
15 | operations = []
16 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0021_merge.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-03-18 10:35
3 |
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0016_reasontojoin_subtitle"),
12 | ("torchbox", "0020_auto_20160317_0955"),
13 | ]
14 |
15 | operations = []
16 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0030_merge.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-06-07 09:20
3 |
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0027_auto_20160603_1718"),
12 | ("torchbox", "0029_auto_20160601_1630"),
13 | ]
14 |
15 | operations = []
16 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0071_merge.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-09-15 10:04
3 |
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0068_auto_20160909_1100"),
12 | ("torchbox", "0070_auto_20160915_1031"),
13 | ]
14 |
15 | operations = []
16 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0072_merge.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.10 on 2016-11-10 10:25
3 |
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0071_auto_rename_global_settings_fields"),
12 | ("torchbox", "0071_merge"),
13 | ]
14 |
15 | operations = []
16 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0101_merge_20180830_1109.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.11 on 2018-08-30 10:09
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0100_auto_20180830_1056"),
12 | ]
13 |
14 | operations = []
15 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/hero/hero--full-screen.html:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/hero/hero.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | title: Example title
3 | desc: Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.
4 | page:
5 | service: Design + build products
6 | section_titles:
7 | - Services
8 | - About support
9 | - Clients
10 | - Blog
11 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0097_merge_20180319_1455.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.10.8 on 2018-03-19 14:55
3 |
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0094_auto_20170908_1245"),
12 | ("torchbox", "0096_revert_pr97"),
13 | ]
14 |
15 | operations = []
16 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/raw_html_block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.
3 | Posuere sollicitudin aliquam ultrices sagittis orci a. Amet consectetur adipiscing elit pellentesque habitant. Id consectetur purus ut faucibus pulvinar elementum integer enim. Id aliquet risus feugiat in ante.
'
4 |
--------------------------------------------------------------------------------
/tbx/propositions/migrations/0012_merge_20230808_1555.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.18 on 2023-08-08 14:55
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 | dependencies = [
8 | ("propositions", "0011_add_social_fields_to_all_page_types"),
9 | ("propositions", "0011_subpropositionpage"),
10 | ]
11 |
12 | operations = []
13 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/value/value.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | item:
3 | heading: Enjoy it
4 | text: Half our waking hours are at work, so we make the most of them. We are positive, supportive, and honest.
5 |
6 | tags:
7 | image:
8 | item.value_image fill-840x400 class="value__image":
9 | raw: ' '
10 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/pages/proposition/sub_proposition.html:
--------------------------------------------------------------------------------
1 | {% extends "patterns/base_page.html" %}
2 | {% load wagtailcore_tags wagtailimages_tags static %}
3 |
4 | {% block content %}
5 |
6 | {% include "patterns/molecules/hero/hero.html" with title=page.strapline desc=page.intro in_page_nav=True %}
7 |
8 | {% include_block page.content %}
9 |
10 | {% endblock %}
11 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/hero/hero--proposition.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | title: The digital product agency for tomorrow's nonprofits .
3 | desc: We help nonprofits like Oxfam, RNIB and Mozilla design and launch world-class digital products, and become more data-driven, connected and efficient organisations along the way.
4 | image:
5 | url: '//placekitten.com/320/568'
6 |
--------------------------------------------------------------------------------
/.git-blame-ignore-revs:
--------------------------------------------------------------------------------
1 | # git-blame ignored revisions
2 | # To configure, run
3 | # git config blame.ignoreRevsFile .git-blame-ignore-revs
4 | # Requires Git > 2.23
5 | # See https://git-scm.com/docs/git-blame#Documentation/git-blame.txt---ignore-revs-fileltfilegt
6 |
7 | # Fix templates formatting with djhtml
8 | # pre-commit run djhtml --color=always --all-files
9 | b867caaabb109ca807559c73086f03fa2812fa31
10 |
--------------------------------------------------------------------------------
/docs/page-models.md:
--------------------------------------------------------------------------------
1 | # Torchbox.com - Page Models
2 |
3 | At the moment we don't have a `BasePage` model that all page models inherit from - they inherit directly from Wagtail's `Page` model. In the future this would be a good thing to refactor.
4 |
5 | For now, if creating new page models, make sure they also inherit from the `SocialFields` mixin, so that social image and text fields are added to the 'promote' tab.
6 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0026_merge.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-05-17 10:41
3 |
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0024_remove_reasontojoin_subtitle"),
12 | ("torchbox", "0025_marketinglandingpagepageclients"),
13 | ]
14 |
15 | operations = []
16 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/key-points.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags %}
2 |
3 | {% include "patterns/molecules/help-block/help-block.html" with title=value.title intro=value.heading_for_key_points items=value.key_points contact=value.contact contact_reasons=value.contact_reasons %}
4 |
5 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/sub_proposition_stream_block.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags %}
2 |
3 | {% for block in value %}
4 | {% if block.block_type in section_block_types %}
5 | {% include_block block %}
6 | {% else %}
7 |
8 | {% include_block block %}
9 |
10 | {% endif %}
11 | {% endfor %}
12 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/impact_report_heading_block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value:
3 | short_heading: The business
4 | heading: Doing business right
5 | image: true
6 |
7 | tags:
8 | image:
9 | value.image fill-1792x597 class="report-section__image":
10 | raw: ' '
11 |
--------------------------------------------------------------------------------
/tbx/services/migrations/0041_merge_0038_call_to_action_0040_update_services_theme.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.18 on 2023-06-27 09:56
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('services', '0038_call_to_action'),
10 | ('services', '0040_update_services_theme'),
11 | ]
12 |
13 | operations = [
14 | ]
15 |
--------------------------------------------------------------------------------
/tbx/work/migrations/0019_remove_workpage_descriptive_title.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-03-28 13:48
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("work", "0018_workpage_client"),
10 | ]
11 |
12 | operations = [
13 | migrations.RemoveField(model_name="workpage", name="descriptive_title",),
14 | ]
15 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0086_fill_filter_spec_field.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2017-01-17 16:36
3 |
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0085_add_filter_spec_field"),
12 | ]
13 |
14 | operations = [
15 | # Removed to make initial migrations work again
16 | ]
17 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/case_studies_section.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags %}
2 | {% include "patterns/organisms/related-content/related-content.html" with id=value.title title=value.title items=featured_case_studies see_more_link=True data_attrs="data-service-section" classes="service-section" see_more_link_text="See more case studies" filter_by=page.filter_by hide_title=hide_title %}
3 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/team-member/team-member.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | item:
3 | title: Tom Dyson
4 | link: '#'
5 | role: 'Technical Director'
6 | profile_image: true
7 |
8 | tags:
9 | image:
10 | item.image fill-400x400 as image:
11 | target_var: image
12 | raw:
13 | url: '//placekitten.com/400/400'
14 |
15 | pageurl:
16 | item:
17 | raw: '#'
18 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/pages/standard/standard_page.html:
--------------------------------------------------------------------------------
1 | {% extends "patterns/base_page.html" %}
2 | {% load wagtailcore_tags wagtailimages_tags static %}
3 |
4 | {% block content %}
5 |
6 | {% include "patterns/molecules/title-block/title-block.html" with item=page tags=false %}
7 |
8 | {% include_block page.body %}
9 | {% include_block page.additional_content %}
10 |
11 | {% endblock %}
12 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/navigation/footer-links.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | footerlinks:
3 | - value:
4 | title: Blog
5 | - value:
6 | title: Work
7 | - value:
8 | title: Team
9 | - value:
10 | title: Privacy
11 | - value:
12 | title: Privacy & Cookies
13 | title: Cookies
14 |
15 | tags:
16 | pageurl:
17 | link.page:
18 | raw: '#'
19 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0024_remove_reasontojoin_subtitle.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-05-12 16:45
3 |
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0023_merge"),
12 | ]
13 |
14 | operations = [
15 | migrations.RemoveField(model_name="reasontojoin", name="subtitle",),
16 | ]
17 |
--------------------------------------------------------------------------------
/tbx/propositions/migrations/0018_merge_20231109_1255.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.20 on 2023-11-09 12:55
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('propositions', '0016_add_work_and_thinking_to_proposition_page'),
10 | ('propositions', '0017_remove_heading_for_processes_field'),
11 | ]
12 |
13 | operations = [
14 | ]
15 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/pages/courses/course_detail_page.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | page:
3 | title: Course page
4 | strapline: Course page Example
5 | sessions: 4 sessions
6 | cost: $100
7 | header_link_text: Find out more
8 | header_link: '#'
9 |
10 | tags:
11 | include_block:
12 | page.body:
13 | template_name: 'patterns/molecules/streamfield/streamfield-example-standard.html'
14 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_course-grid.scss:
--------------------------------------------------------------------------------
1 | .course-grid-title {
2 | @include font-size(ml);
3 | margin-bottom: 0;
4 | }
5 |
6 | .course-grid {
7 | display: grid;
8 | gap: 30px;
9 | margin: 25px 0 100px;
10 |
11 | @include media-query(medium-large) {
12 | grid-template-columns: repeat(2, 1fr);
13 | max-width: 1280px;
14 | gap: 50px;
15 | margin: 50px 0 120px;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
3 | "version": "0.2.0",
4 | "configurations": [
5 | {
6 | "name": "Python: Django",
7 | "type": "python",
8 | "request": "launch",
9 | "program": "${workspaceFolder}/manage.py",
10 | "args": ["runserver", "0:8000"],
11 | "django": true,
12 | "justMyCode": false
13 | }
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0103_merge_20180918_1304.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.11 on 2018-09-18 12:04
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0102_auto_20180830_1109"),
12 | ("torchbox", "0101_auto_20180912_1622"),
13 | ]
14 |
15 | operations = []
16 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0104_merge_20180928_1009.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.11 on 2018-09-28 09:09
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0103_merge_20180918_1304"),
12 | ("torchbox", "0102_workpage_feed_image"),
13 | ]
14 |
15 | operations = []
16 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0052_merge.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-08-26 11:13
3 |
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0031_blogpage_canonical_url"),
12 | ("torchbox", "0051_mainmenu_mainmenuitem"),
13 | ("torchbox", "0050_auto_20160826_1123"),
14 | ]
15 |
16 | operations = []
17 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0016_auto_20160205_1724.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 |
4 | from django.db import models, migrations
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ("torchbox", "0015_auto_20160205_1536"),
11 | ]
12 |
13 | operations = [
14 | migrations.AlterModelOptions(
15 | name="googleadgrantapplication", options={"ordering": ["-date"]},
16 | ),
17 | ]
18 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/navigation/mobile-nav.html:
--------------------------------------------------------------------------------
1 | {% load navigation_tags %}
2 |
3 |
4 |
5 |
6 |
7 | {% primarynav is_home=False is_desktop=False %}
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_related-content.scss:
--------------------------------------------------------------------------------
1 | .related-content {
2 | position: relative;
3 | background: var(--color--white);
4 | padding-top: ($gutter * 5);
5 |
6 | &__list {
7 | padding-top: ($gutter * 2);
8 | }
9 |
10 | &--bottom-margin {
11 | margin-bottom: ($gutter * 2);
12 |
13 | @include media-query(medium) {
14 | margin-bottom: ($gutter * 4);
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | # Torchbox.com technical documentation
2 |
3 | [TOC]
4 |
5 | ## Project overview
6 |
7 | This is the main website for torchbox.com, built on the [Wagtail CMS](https://wagtail.org/).
8 |
9 | To start working on this project, please refer to the [README](https://github.com/torchbox/wagtail-torchbox/blob/main/README.md).
10 |
11 | ## External integrations
12 |
13 | The jobs listing on the site is pulled from [PeopleHR](https://www.peoplehr.com/).
14 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/three_column_image_grid_block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value:
3 | items:
4 | - image: true
5 | text: This is the first policy
6 | - image: true
7 | text: This is the second policy
8 | - image: true
9 | text: This is the third policy
10 |
11 | tags:
12 | image:
13 | item.image fill-100x100:
14 | raw: ' '
15 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render
2 |
3 | from .forms import ExampleForm
4 |
5 |
6 | def example_form(request):
7 | if request.method == "POST":
8 | form = ExampleForm(request.POST)
9 | form.add_error(None, "An example non-field error.")
10 | else:
11 | form = ExampleForm()
12 |
13 | return render(
14 | request, "patterns/_pattern_library_only/example_form.html", {"form": form}
15 | )
16 |
--------------------------------------------------------------------------------
/tbx/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for tbx project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.wsgi import get_wsgi_application
13 |
14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tbx.settings.production")
15 |
16 | application = get_wsgi_application()
17 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/_pattern_library_only/streamfield/story_container.html:
--------------------------------------------------------------------------------
1 | {% include "patterns/molecules/streamfield/blocks/heading_block.html" %}
2 | {% include "patterns/molecules/streamfield/blocks/image_block.html" %}
3 | {% include "patterns/molecules/streamfield/blocks/quote_block.html" %}
4 | {% include "patterns/molecules/streamfield/blocks/call_to_action_block.html" %}
5 | {% include "patterns/molecules/streamfield/blocks/document_block.html" %}
6 |
7 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/atoms/icons/icon.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags %}
2 |
3 | {# Use with include, e.g. `{% include "patterns/atoms/icons/icon.html" with name="mybutton" classname="icon--stroke button__icon" %}` #}
4 |
5 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tbx/work/migrations/0018_workpage_client.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-02-06 01:28
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("work", "0017_listing_summary_not_required"),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name="workpage", name="client", field=models.TextField(blank=True),
15 | ),
16 | ]
17 |
--------------------------------------------------------------------------------
/tbx/blog/migrations/0012_remove_blogpage_marketing_only.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.16 on 2019-01-22 13:10
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("blog", "0011_helptext"),
12 | ]
13 |
14 | operations = [
15 | migrations.RemoveField(model_name="blogpage", name="marketing_only",),
16 | ]
17 |
--------------------------------------------------------------------------------
/tbx/blog/migrations/0014_remove_blogpage_intro.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.16 on 2019-01-22 13:16
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("blog", "0013_blogpage_listing_summary"),
12 | ]
13 |
14 | operations = [
15 | migrations.RemoveField(model_name="blogpage", name="intro",),
16 | ]
17 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/blog-item/blog-item.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | item:
3 | author:
4 | name: Paul Vetch
5 | role: Strategy Director
6 | title: We already dropped Drupal - maybe it’s time for you to do the same.
7 |
8 | tags:
9 | image:
10 | item.author.image fill-100x100 class="avatar__image":
11 | raw: ' '
12 | pageurl:
13 | item:
14 | raw: '#'
15 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/video_block.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {% for source in value.video.sources %}
4 |
5 | {% endfor %}
6 |
7 |
8 |
--------------------------------------------------------------------------------
/tbx/services/migrations/0013_auto_20190207_0252.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-02-07 02:52
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("services", "0012_servicepageherolink"),
10 | ]
11 |
12 | operations = [
13 | migrations.RemoveField(model_name="servicepageherolink", name="page",),
14 | migrations.DeleteModel(name="ServicePageHeroLink",),
15 | ]
16 |
--------------------------------------------------------------------------------
/docker/bashrc.sh:
--------------------------------------------------------------------------------
1 | # Note: This file is loaded on all environments, even production.
2 |
3 | alias dj="python manage.py"
4 |
5 | if [ "$BUILD_ENV" = "dev" ]; then
6 | alias djrun="python manage.py runserver 0.0.0.0:8000"
7 | alias djtest="python manage.py test --settings=tbx.settings.test"
8 | fi
9 |
10 | # nvm
11 | if [ -a "$HOME/.nvm/nvm.sh" ]; then
12 | export NVM_DIR="$HOME/.nvm"
13 | source "$NVM_DIR/nvm.sh"
14 | fi
15 |
16 | alias honcho="honcho -f docker/Procfile"
17 |
--------------------------------------------------------------------------------
/tbx/blog/migrations/0018_remove_blogpage_colour.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.16 on 2019-01-22 15:19
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("blog", "0017_map_tags_to_related_services"),
12 | ]
13 |
14 | operations = [
15 | migrations.RemoveField(model_name="blogpage", name="colour",),
16 | ]
17 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/event-item/event-item.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | item:
3 | author:
4 | name: Paul Vetch
5 | role: Strategy Director
6 | title: We already dropped Drupal - maybe it’s time for you to do the same.
7 |
8 | tags:
9 | image:
10 | item.author.image fill-100x100 class="avatar__image":
11 | raw: ' '
12 | pageurl:
13 | item:
14 | raw: '#'
15 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/paragraph_with_image_block.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags wagtailimages_tags %}
2 |
3 |
4 |
5 | {{ value.text|richtext }}
6 |
7 |
8 |
9 | {% image value.image width-500 %}
10 |
11 |
12 |
--------------------------------------------------------------------------------
/tbx/work/migrations/0012_remove_workpage_intro.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.16 on 2019-01-22 14:34
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("work", "0011_remove_workpage_marketing_only"),
12 | ]
13 |
14 | operations = [
15 | migrations.RemoveField(model_name="workpage", name="intro",),
16 | ]
17 |
--------------------------------------------------------------------------------
/browsersync.config.js:
--------------------------------------------------------------------------------
1 | const host = process.env.PROXY_HOST || 'localhost';
2 | const port = process.env.PROXY_PORT || '8000';
3 |
4 | module.exports = {
5 | proxy: {
6 | target: `${host}:${port}`,
7 | proxyOptions: {
8 | changeOrigin: false,
9 | },
10 | },
11 | serveStatic: [
12 | {
13 | route: '/static',
14 | dir: 'tbx/static_compiled',
15 | },
16 | ],
17 | files: 'tbx/static_compiled',
18 | };
19 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/paragraph_with_image_block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value:
3 | text: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Non nisi est sit amet facilisis magna etiam tempor orci.
4 | image: true
5 | image_alignment: right
6 |
7 | tags:
8 | image:
9 | value.image width-500:
10 | raw: ' '
11 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/paragraph_with_quote_block.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags %}
2 |
3 |
4 |
5 | {{ value.text|richtext }}
6 |
7 |
8 |
9 | {{ value.quote }}
10 | {{ value.attribution }}
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/pullquote_block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value:
3 | quote: We are so pleased with the result - a beautiful website telling Oxfam's story through the voices of the people we work with.
4 | name: Theo Smart
5 | role: Head of Digital
6 | link:
7 | 0:
8 | value:
9 | link: '#'
10 | text: See Oxfam's case study
11 |
12 | tags:
13 | pageurl:
14 | link:
15 | raw: '#'
16 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_filter.scss:
--------------------------------------------------------------------------------
1 | .filter {
2 | display: flex;
3 | align-items: center;
4 | justify-content: flex-start;
5 | flex-wrap: wrap;
6 |
7 | &__tag {
8 | @include font-size(xxs);
9 | box-sizing: content-box;
10 | padding: 2px 8px;
11 | margin-right: 10px;
12 |
13 | &--active {
14 | border: 2px solid var(--color--coral);
15 | color: var(--color--coral);
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0110_rename_blogpagetaglist_to_tag.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.16 on 2019-01-15 22:37
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0109_move_blog_into_new_app"),
12 | ]
13 |
14 | operations = [
15 | migrations.RenameModel(old_name="BlogPageTagList", new_name="Tag",),
16 | ]
17 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/two_column_text_grid_block.html:
--------------------------------------------------------------------------------
1 | {% load wagtailimages_tags %}
2 |
3 |
4 | {% for item in value.items %}
5 |
6 | {% image item.image fill-70x70 %}
7 |
{{ item.heading }}
8 |
{{ item.text }}
9 |
10 | {% endfor %}
11 |
12 |
--------------------------------------------------------------------------------
/tbx/work/migrations/0011_remove_workpage_marketing_only.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.16 on 2019-01-22 13:10
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("work", "0010_rename_streamfield_to_body"),
12 | ]
13 |
14 | operations = [
15 | migrations.RemoveField(model_name="workpage", name="marketing_only",),
16 | ]
17 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0023_merge.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-05-12 11:51
3 |
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0021_merge"),
12 | (
13 | "torchbox",
14 | "0022_signupformpage_signupformpagebullet_signupformpagelogo_signupformpagequote_signupformpageresponse",
15 | ),
16 | ]
17 |
18 | operations = []
19 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0044_aboutpage_heading.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-07-07 15:50
3 |
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0043_auto_20160707_1648"),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name="aboutpage", name="heading", field=models.TextField(blank=True),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/tbx/blog/migrations/0009_remove_blogindexpage_show_in_play_menu.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.16 on 2019-01-21 13:52
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("blog", "0008_remove_blogpage_body"),
12 | ]
13 |
14 | operations = [
15 | migrations.RemoveField(model_name="blogindexpage", name="show_in_play_menu",),
16 | ]
17 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0117_remove_standardpage_middle_break.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.16 on 2019-01-22 13:22
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0116_delete_marketing_landing_page"),
12 | ]
13 |
14 | operations = [
15 | migrations.RemoveField(model_name="standardpage", name="middle_break",),
16 | ]
17 |
--------------------------------------------------------------------------------
/tbx/taxonomy/migrations/0003_service_description.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-02-06 01:18
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("taxonomy", "0002_initial_services"),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name="service",
15 | name="description",
16 | field=models.TextField(blank=True),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0114_remove_standardpage_show_in_play_menu.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.16 on 2019-01-21 13:52
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0113_move_people_into_new_app_2"),
12 | ]
13 |
14 | operations = [
15 | migrations.RemoveField(model_name="standardpage", name="show_in_play_menu",),
16 | ]
17 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/small_image_with_text_block.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags wagtailimages_tags %}
2 |
3 |
4 | {% image value.image fill-80x80 class="small-image-with-text__image" alt="" %}
5 |
6 |
7 |
{{ value.title }}
8 |
9 |
10 | {{ value.text|richtext }}
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/three_column_image_grid_block.html:
--------------------------------------------------------------------------------
1 | {% load wagtailimages_tags %}
2 |
3 |
4 | {% for item in value.items %}
5 |
6 |
7 | {% image item.image height-80 %}
8 |
9 |
{{ item.text }}
10 |
11 | {% endfor %}
12 |
13 |
--------------------------------------------------------------------------------
/tbx/services/migrations/0038_data_migration_subservice_theme.py:
--------------------------------------------------------------------------------
1 | from django.db import migrations
2 |
3 | def update_theme(apps, schema_editor):
4 | page = apps.get_model('services', 'SubServicePage')
5 | page.objects.filter(theme='dark--transparent').update(theme='light')
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('services', '0037_alter_subservicepage_content'),
11 | ]
12 |
13 | operations = [
14 | migrations.RunPython(update_theme),
15 | ]
16 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0126_jobindexpage_jobs_xml_feed.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.12 on 2020-08-07 14:49
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("torchbox", "0125_auto_20190216_1713"),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name="jobindexpage",
15 | name="jobs_xml_feed",
16 | field=models.URLField(blank=True),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/tbx/services/migrations/0021_auto_20190211_0705.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-02-11 07:05
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("services", "0020_servicepage_greeting_image"),
10 | ]
11 |
12 | operations = [
13 | migrations.RenameField(
14 | model_name="servicepage",
15 | old_name="greeting_image",
16 | new_name="greeting_image_type",
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_header.scss:
--------------------------------------------------------------------------------
1 | .header {
2 | $root: &;
3 | @include z-index(header);
4 | width: 100%;
5 | position: absolute;
6 | top: 0;
7 |
8 | &__inner {
9 | @include container();
10 | display: flex;
11 | flex-direction: column;
12 | align-items: flex-start;
13 | padding: $gutter 0;
14 |
15 | @include media-query(large) {
16 | flex-direction: row;
17 | padding: ($gutter * 2) 0 0;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/process-item/process-item.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags %}
2 |
3 |
{{ item.title }}
4 |
{{ item.description | richtext }}
5 | {% if item.link %}
6 |
11 | {% endif %}
12 |
13 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/small_image_with_text_block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value:
3 | title: 100% renewable gas
4 | text: >
5 | We're still heating on gas in our Bristol office, but we're excited to have moved this year to a 100% certified renewable gas supply (SSE's Green Gas Plus).
6 |
7 | tags:
8 | image:
9 | value.image fill-80x80 class="small-image-with-text__image":
10 | raw: ' '
11 |
--------------------------------------------------------------------------------
/tbx/services/migrations/0009_auto_20190206_2323.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-02-06 23:23
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("services", "0008_servicepage_is_darktheme"),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterField(
14 | model_name="servicepage",
15 | name="is_darktheme",
16 | field=models.BooleanField(default=False),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/abstracts/_functions.scss:
--------------------------------------------------------------------------------
1 | // Strip the unit from the given value and return the value
2 | @use 'sass:math';
3 |
4 | @function strip-unit($value) {
5 | @return math.div($value, $value * 0 + 1);
6 | }
7 |
8 | // Return an em unit based on the pixel value and context
9 | @function rem($px, $context: $base-font-size) {
10 | @return #{strip-unit(math.div($px, strip-unit($context)))}rem;
11 | }
12 |
13 | // Map z-index keys
14 | @function z-index($key) {
15 | @return map-get($z-index, $key);
16 | }
17 |
--------------------------------------------------------------------------------
/tbx/work/migrations/0022_workpage_date.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.17 on 2021-02-17 14:51
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("work", "0021_update_streamblock_templates"),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name="workpage",
15 | name="date",
16 | field=models.DateField(null=True, verbose_name="Post date"),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0049_auto_20160819_1421.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-08-19 13:21
3 |
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0048_personpage_is_senior"),
12 | ]
13 |
14 | operations = [
15 | migrations.RemoveField(model_name="personindexpage", name="intro",),
16 | migrations.RemoveField(model_name="personindexpage", name="show_in_play_menu",),
17 | ]
18 |
--------------------------------------------------------------------------------
/tbx/people/migrations/0008_personpage_short_intro.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-02-13 01:12
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("people", "0007_culturepage_culturepagelink"),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name="personpage",
15 | name="short_intro",
16 | field=models.TextField(blank=True, null=True),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/tbx/people/migrations/0009_personpage_alt_short_intro.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-02-16 07:42
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("people", "0008_personpage_short_intro"),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name="personpage",
15 | name="alt_short_intro",
16 | field=models.TextField(blank=True, null=True),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/tbx/services/migrations/0008_servicepage_is_darktheme.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-02-06 23:22
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("services", "0007_servicepagekeypoint_linked_page"),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name="servicepage",
15 | name="is_darktheme",
16 | field=models.BooleanField(default=True),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0053_jobindexpage_reasons_intro.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-08-26 11:49
3 |
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0052_merge"),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name="jobindexpage",
17 | name="reasons_intro",
18 | field=models.TextField(blank=True),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0062_auto_20160905_1151.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-09-05 10:51
3 |
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0061_auto_20160902_1609"),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name="blogindexpage",
17 | name="intro",
18 | field=models.TextField(blank=True),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0014_workpage_show_in_play_menu.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 |
4 | from django.db import models, migrations
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ("torchbox", "0013_auto_20150720_1154"),
11 | ]
12 |
13 | operations = [
14 | migrations.AddField(
15 | model_name="workpage",
16 | name="show_in_play_menu",
17 | field=models.BooleanField(default=False),
18 | preserve_default=True,
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0048_personpage_is_senior.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-08-19 13:12
3 |
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0047_homepagehero_text"),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name="personpage",
17 | name="is_senior",
18 | field=models.BooleanField(default=False),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0061_auto_20160902_1609.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-09-02 15:09
3 |
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0060_auto_20160901_1658"),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name="workpage",
17 | name="visit_the_site",
18 | field=models.URLField(blank=True),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0127_jobindexpage_intro.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.12 on 2020-08-13 14:33
2 |
3 | from django.db import migrations
4 | import wagtail.fields
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ("torchbox", "0126_jobindexpage_jobs_xml_feed"),
11 | ]
12 |
13 | operations = [
14 | migrations.AddField(
15 | model_name="jobindexpage",
16 | name="intro",
17 | field=wagtail.fields.RichTextField(blank=True),
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/tbx/people/migrations/0018_update_contact.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.12 on 2021-01-22 07:22
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("people", "0017_update_streamblock_templates"),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterField(
14 | model_name="contact",
15 | name="default_contact",
16 | field=models.BooleanField(blank=True, default=False, null=True),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0016_reasontojoin_subtitle.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 |
4 | from django.db import models, migrations
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ("torchbox", "0015_auto_20151105_1715"),
11 | ]
12 |
13 | operations = [
14 | migrations.AddField(
15 | model_name="reasontojoin",
16 | name="subtitle",
17 | field=models.CharField(default="", max_length=255),
18 | preserve_default=False,
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0031_blogpage_canonical_url.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-08-16 08:48
3 |
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0030_merge"),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name="blogpage",
17 | name="canonical_url",
18 | field=models.URLField(blank=True, max_length=255),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/tbx/core/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 | from django.urls import reverse
3 |
4 |
5 | class SecurityViewTestCase(TestCase):
6 | url = reverse("security-txt")
7 |
8 | def test_accessible(self) -> None:
9 | response = self.client.get(self.url)
10 | self.assertEqual(response.status_code, 200)
11 | self.assertEqual(
12 | response.context["security_txt"],
13 | "http://testserver/.well-known/security.txt",
14 | )
15 | self.assertIn("no-cache", response["Cache-Control"])
16 |
--------------------------------------------------------------------------------
/tbx/people/migrations/0010_contact_default_contact.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-02-16 17:44
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("people", "0009_personpage_alt_short_intro"),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name="contact",
15 | name="default_contact",
16 | field=models.BooleanField(blank=True, null=True, unique=True),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/tbx/services/migrations/0022_servicepage_heading_for_processes.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-02-13 05:45
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("services", "0021_auto_20190211_0705"),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name="servicepage",
15 | name="heading_for_processes",
16 | field=models.TextField(blank=True, null=True),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/tbx/taxonomy/admin.py:
--------------------------------------------------------------------------------
1 | from wagtail.snippets.views.snippets import SnippetViewSet, SnippetViewSetGroup
2 |
3 | from . import models
4 |
5 |
6 | class ServiceModelAdmin(SnippetViewSet):
7 | model = models.Service
8 | base_url_path = "taxonomy/service"
9 | list_display = ("name", "slug", "sort_order")
10 | ordering = ["sort_order"]
11 |
12 |
13 | class TaxonomyModelAdminGroup(SnippetViewSetGroup):
14 | menu_label = "Taxonomy"
15 | menu_icon = "folder-open-inverse"
16 | menu_order = 750
17 | items = [ServiceModelAdmin]
18 |
--------------------------------------------------------------------------------
/tbx/work/migrations/0016_rename_summary_to_listing_summary.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.16 on 2019-01-22 17:15
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("work", "0015_workpage_body_word_count"),
12 | ]
13 |
14 | operations = [
15 | migrations.RenameField(
16 | model_name="workpage", old_name="summary", new_name="listing_summary",
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/tbx/work/migrations/0031_alter_workpage_date.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.20 on 2023-10-10 23:03
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("work", "0030_add_social_fields_to_all_page_types"),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterField(
14 | model_name="workpage",
15 | name="date",
16 | field=models.DateField(blank=True, null=True, verbose_name="Post date"),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/tbx/core/fields.py:
--------------------------------------------------------------------------------
1 | import re
2 |
3 | from django.core.validators import RegexValidator
4 | from django.db import models
5 | from django.utils.translation import gettext_lazy as _
6 |
7 | color_re = re.compile(r"^[A-Fa-f0-9]{6}$")
8 | color_validator = RegexValidator(color_re, _("Enter a valid color."), "invalid")
9 |
10 |
11 | class ColorField(models.CharField):
12 | default_validators = [color_validator]
13 |
14 | def __init__(self, *args, **kwargs):
15 | kwargs["max_length"] = 6
16 | super(ColorField, self).__init__(*args, **kwargs)
17 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/author/author.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | author:
3 | name: Nick Lee
4 | role: Designer
5 | item:
6 | date: 07 Aug ’20
7 | read_time: 5
8 | related_services:
9 | all:
10 | - { name: Digital products, slug: digital-products }
11 |
12 | tags:
13 | image:
14 | author.image fill-100x100 as image:
15 | target_var: image
16 | raw:
17 | alt: 'Alt'
18 | url: 'https://placekitten.com/100/100'
19 | pageurl:
20 | author.person_page:
21 | raw: '#'
22 |
--------------------------------------------------------------------------------
/tbx/static_src/images/icons/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Torchbox",
3 | "short_name": "Torchbox",
4 | "icons": [
5 | {
6 | "src": "android-chrome-192x192.png",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | },
10 | {
11 | "src": "android-chrome-256x256.png",
12 | "sizes": "256x256",
13 | "type": "image/png"
14 | }
15 | ],
16 | "theme_color": "#ffffff",
17 | "background_color": "#ffffff",
18 | "display": "standalone"
19 | }
20 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_team.scss:
--------------------------------------------------------------------------------
1 | .team {
2 | position: relative;
3 | background-color: var(--color--white);
4 | padding: $gutter 0;
5 |
6 | @include media-query(medium) {
7 | padding-top: ($gutter * 4.5);
8 | }
9 |
10 | @include media-query(large) {
11 | padding-top: ($gutter * 6.5);
12 | }
13 |
14 | &__container {
15 | @include container();
16 | }
17 |
18 | &__list {
19 | display: flex;
20 | flex-wrap: wrap;
21 | margin-bottom: ($gutter * 2);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/tbx/people/migrations/0025_auto_20210505_1057.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.17 on 2021-05-05 09:57
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("people", "0024_auto_20210416_1406"),
10 | ]
11 |
12 | operations = [
13 | migrations.RemoveField(model_name="culturepage", name="body",),
14 | migrations.RemoveField(model_name="culturepage", name="contact",),
15 | migrations.RemoveField(model_name="culturepage", name="strapline_visible",),
16 | ]
17 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0050_auto_20160826_1123.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-08-26 10:23
3 |
4 |
5 | from django.db import migrations
6 | import wagtail.fields
7 |
8 |
9 | class Migration(migrations.Migration):
10 |
11 | dependencies = [
12 | ("torchbox", "0049_auto_20160819_1421"),
13 | ]
14 |
15 | operations = [
16 | migrations.AlterField(
17 | model_name="homepage",
18 | name="intro_body",
19 | field=wagtail.fields.RichTextField(blank=True),
20 | ),
21 | ]
22 |
--------------------------------------------------------------------------------
/tbx/static_src/images/cssBackgrounds/quote.svg:
--------------------------------------------------------------------------------
1 |
3 | Quote mark
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/tbx/work/migrations/0009_remove_play_fields.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.16 on 2019-01-21 13:52
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("work", "0008_remove_workpage_body"),
12 | ]
13 |
14 | operations = [
15 | migrations.RemoveField(model_name="workindexpage", name="show_in_play_menu",),
16 | migrations.RemoveField(model_name="workpage", name="show_in_play_menu",),
17 | ]
18 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/embed_plus_cta_block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value:
3 | title: Work with the best in the business
4 | intro: We're all business owners so we're 100% engaged in the quality of our work. Engineers, product people, designers, analysts with deep expertise in the nonprofit world.
5 | link: '#'
6 | button_text: Meet the team
7 | embed: VIDEO
8 |
9 | tags:
10 | pageurl:
11 | value.link:
12 | raw: '#'
13 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/pages/errors/404.html:
--------------------------------------------------------------------------------
1 | {% extends "patterns/base_page.html" %}
2 |
3 | {% block title %}Page not found{% endblock %}
4 | {% block body_class %}template__error{% endblock %}
5 | {% block content %}
6 |
16 | {% endblock %}
17 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0073_auto_20161026_1023.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-10-26 09:23
3 |
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0072_auto_20161026_0959"),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name="globalsettings",
17 | name="contact_email",
18 | field=models.EmailField(help_text="Email address", max_length=255),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/tbx/people/migrations/0014_contactreasonslist_is_default_not_unique.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-03-20 15:19
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("people", "0013_culturepage_strapline_visible"),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterField(
14 | model_name="contactreasonslist",
15 | name="is_default",
16 | field=models.BooleanField(blank=True, default=False, null=True),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/email-signup/email-signup.html:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/organisms/header/header.html:
--------------------------------------------------------------------------------
1 | {% load navigation_tags %}
2 |
14 |
--------------------------------------------------------------------------------
/tbx/services/migrations/0039_data_migration_service_theme.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.18 on 2023-06-23 10:08
2 |
3 | from django.db import migrations
4 |
5 | def update_theme(apps, schema_editor):
6 | page = apps.get_model('services', 'ServicePage')
7 | page.objects.filter(theme='dark--transparent').update(theme='light')
8 |
9 |
10 | class Migration(migrations.Migration):
11 |
12 | dependencies = [
13 | ('services', '0038_data_migration_subservice_theme'),
14 | ]
15 |
16 | operations = [
17 | migrations.RunPython(update_theme),
18 | ]
19 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/related-item/related-item.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | item:
3 | title: We’ve launched a supporter-centred Wagtail website for Oxfam GB
4 | subtitle: Oxfam
5 | description: Following the launch of a new public engagement strategy Oxfam needed a website to ‘make it happen’ by reshaping and tailoring the entire experience to the needs of Oxfam’s supporters.
6 | url: '#'
7 |
8 | tags:
9 | image:
10 | item.image width-1280 as image:
11 | target_var: image
12 | raw:
13 | url: '//placekitten.com/1280/800'
14 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/key_points_summary.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags %}
2 |
3 |
4 | {% for key_point in value %}
5 |
6 |
11 |
{{ key_point.intro }}
12 |
13 | {% endfor %}
14 |
15 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/team-member/team-member.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags wagtailimages_tags %}
2 |
3 | {% image item.image fill-550x550 as image %}
4 |
11 |
--------------------------------------------------------------------------------
/tbx/services/migrations/0023_key_points_heading_not_required.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-03-15 13:23
2 |
3 | from django.db import migrations
4 | import wagtail.fields
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ("services", "0022_servicepage_heading_for_processes"),
11 | ]
12 |
13 | operations = [
14 | migrations.AlterField(
15 | model_name="servicepage",
16 | name="heading_for_key_points",
17 | field=wagtail.fields.RichTextField(blank=True),
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0056_workpage_visit_the_site.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-08-30 16:26
3 |
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0055_auto_20160830_1705"),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name="workpage",
17 | name="visit_the_site",
18 | field=models.URLField(default=""),
19 | preserve_default=False,
20 | ),
21 | ]
22 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0095_set_blogpages_show_in_menus_true.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.12 on 2017-10-10 08:57
3 |
4 |
5 | from django.db import migrations
6 |
7 |
8 | def set_blogpages_show_in_menus_true(apps, schema_editor):
9 | BlogPage = apps.get_model("torchbox", "BlogPage")
10 | BlogPage.objects.all().update(show_in_menus=True)
11 |
12 |
13 | class Migration(migrations.Migration):
14 |
15 | dependencies = [
16 | ("torchbox", "0094_merge"),
17 | ]
18 |
19 | operations = [migrations.RunPython(set_blogpages_show_in_menus_true)]
20 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0047_homepagehero_text.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-08-19 12:33
3 |
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0046_auto_20160718_1554"),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name="homepagehero",
17 | name="text",
18 | field=models.CharField(default="", max_length=255),
19 | preserve_default=False,
20 | ),
21 | ]
22 |
--------------------------------------------------------------------------------
/tbx/people/migrations/0011_auto_20190216_1748.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-02-16 17:48
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("people", "0010_contact_default_contact"),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterField(
14 | model_name="contact",
15 | name="default_contact",
16 | field=models.BooleanField(
17 | blank=True, default=False, null=True, unique=True
18 | ),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/paragraph_with_quote_block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value:
3 | text: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Non nisi est sit amet facilisis magna etiam tempor orci.
4 | quote: Accumsan tortor posuere ac ut consequat semper. Dolor magna eget est lorem ipsum dolor sit. Malesuada fames ac turpis egestas. Ac placerat vestibulum lectus mauris ultrices eros in. Fusce ut placerat orci nulla pellentesque dignissim enim.
5 | attribution: Maria dela Cruz
6 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/markdown_block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value: '# Lorem ipsum dolor sit amet, consectetur adipiscing elit
3 | ## Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium,
4 | Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur?'
5 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_three-col-image.scss:
--------------------------------------------------------------------------------
1 | .three-col-image {
2 | display: grid;
3 | gap: 30px;
4 | margin: 30px 0;
5 |
6 | @include media-query(medium) {
7 | grid-template-columns: repeat(3, 1fr);
8 | }
9 |
10 | &__text {
11 | @include font-size(s);
12 | color: var(--color--stone);
13 | line-height: 31px;
14 | font-weight: $weight--bold;
15 | text-align: center;
16 | margin: 25px 0 0;
17 | }
18 |
19 | &__image-wrapper {
20 | display: grid;
21 | place-items: center;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | /tbx/static_compiled/
2 | /tbx/settings/local.py
3 |
4 | /Dockerfile
5 | /docker/Dockerfile*
6 |
7 | .git
8 | **/__pycache__
9 | *.pyc
10 | .DS_Store
11 | *.swp
12 | /venv/
13 | /static/
14 | /media/
15 | /tmp/
16 | /.vagrant/
17 | /Vagrantfile.local
18 | node_modules/
19 | coverage
20 | /npm-debug.log
21 | /.idea/
22 | /.devcontainer/
23 |
24 | # Distribution / packaging
25 | .Python
26 | env/
27 | build/
28 | develop-eggs/
29 | dist/
30 | downloads/
31 | eggs/
32 | .eggs/
33 | lib/
34 | lib64/
35 | parts/
36 | sdist/
37 | var/
38 | wheels/
39 | *.egg-info/
40 | .installed.cfg
41 | *.egg
42 |
--------------------------------------------------------------------------------
/tbx/images/migrations/0003_alter_customimage_file_hash.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.12 on 2022-04-22 14:09
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("images", "0002_copy_custom_images"),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterField(
14 | model_name="customimage",
15 | name="file_hash",
16 | field=models.CharField(
17 | blank=True, db_index=True, editable=False, max_length=40
18 | ),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/tbx/navigation/migrations/0005_auto_20210802_1540.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.17 on 2021-08-02 14:40
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("navigation", "0004_navigationsettings_footer_top_links"),
10 | ]
11 |
12 | operations = [
13 | migrations.RemoveField(
14 | model_name="navigationsettings", name="footer_navigation",
15 | ),
16 | migrations.RemoveField(
17 | model_name="navigationsettings", name="secondary_navigation",
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/tbx/navigation/migrations/0010_remove_navigationsettings_footer_teasers.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.18 on 2023-06-28 11:26
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | (
10 | "navigation",
11 | "0009_add_externallink_to_linkblock_and_remove_footer_top_links_from_navigationsettings",
12 | ),
13 | ]
14 |
15 | operations = [
16 | migrations.RemoveField(
17 | model_name="navigationsettings",
18 | name="footer_teasers",
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/tbx/settings/__init__.py:
--------------------------------------------------------------------------------
1 | # If you want to avoid weird side effects, do not import dev settings here.
2 | # For example, if your dev settings do something like
3 | #
4 | # INSTALLED_APPS += [
5 | # 'debug_toolbar',
6 | # ]
7 | #
8 | # You will have `debug_toolbar` enabled even if you run
9 | # your application in production settings because `INSTALLED_APPS` will be changed during import
10 | #
11 | # It's better to explicitly specify settings file
12 | # by setting the `DJANGO_SETTINGS_MODULE` environment variable
13 | # or passing the --settings argument into your manage commands, when possible.
14 |
--------------------------------------------------------------------------------
/tbx/people/forms.py:
--------------------------------------------------------------------------------
1 | from tbx.people import models
2 | from wagtail.admin.forms import WagtailAdminPageForm
3 |
4 |
5 | class ContactForm(WagtailAdminPageForm):
6 | def clean_default_contact(self):
7 | default_contact = self.cleaned_data["default_contact"]
8 |
9 | # If user wants to enable the default contact option
10 | if default_contact:
11 | # Make sure only one default contact existing
12 | models.Contact.objects.filter(default_contact=True).update(
13 | default_contact=False
14 | )
15 |
16 | return default_contact
17 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/job-item/job-item.html:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/navigation/primary-nav.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | job_count: 3
3 | primarynav:
4 | - value:
5 | page:
6 | title: Design + build products
7 | - value:
8 | page:
9 | title: Wagtail CMS
10 | title: Wagtail CMS services
11 | - value:
12 | page:
13 | title: Digital marketing
14 | - value:
15 | page:
16 | careers_link: True
17 | title: Careers
18 |
19 | tags:
20 | pageurl:
21 | link.page:
22 | raw: '#'
23 | link.page.careers_page:
24 | raw: '#'
25 |
--------------------------------------------------------------------------------
/tbx/blog/migrations/0019_blogpage_body_word_count.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.16 on 2019-01-22 15:25
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("blog", "0018_remove_blogpage_colour"),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name="blogpage",
17 | name="body_word_count",
18 | field=models.PositiveIntegerField(editable=False, null=True),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0032_jobindexpagejob_job_intro.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-06-17 13:40
3 |
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0031_blogpage_homepage_color"),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name="jobindexpagejob",
17 | name="job_intro",
18 | field=models.CharField(default="", max_length=255),
19 | preserve_default=False,
20 | ),
21 | ]
22 |
--------------------------------------------------------------------------------
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
2 | // https://github.com/microsoft/vscode-dev-containers/tree/v0.163.1/containers/docker-existing-docker-compose
3 | {
4 | "name": "Existing Docker Compose (Extend)",
5 | "dockerComposeFile": ["../docker-compose.yml"],
6 | "service": "web",
7 | "workspaceFolder": "/app",
8 | "settings": {
9 | "terminal.integrated.shell.linux": "bash",
10 | "python.pythonPath": "/usr/local/bin/python"
11 | },
12 | "extensions": ["ms-python.python", "editorconfig.editorconfig"]
13 | }
14 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0105_torchboximage_file_hash.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.11 on 2018-10-15 12:25
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0104_merge_20180928_1009"),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name="torchboximage",
17 | name="file_hash",
18 | field=models.CharField(blank=True, editable=False, max_length=40),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/tbx/people/migrations/0032_alter_contact_phone_number.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.16 on 2023-03-13 15:00
2 |
3 | from django.db import migrations
4 | import phonenumber_field.modelfields
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('people', '0031_auto_20220422_1515'),
11 | ]
12 |
13 | operations = [
14 | migrations.AlterField(
15 | model_name='contact',
16 | name='phone_number',
17 | field=phonenumber_field.modelfields.PhoneNumberField(blank=True, max_length=128, null=True, region=None),
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/tbx/propositions/migrations/0009_alter_propositionpage_theme.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.16 on 2023-04-11 21:53
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('propositions', '0008_auto_20230317_1144'),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterField(
14 | model_name='propositionpage',
15 | name='theme',
16 | field=models.CharField(choices=[('light', 'Light'), ('coral', 'Coral'), ('dark', 'Dark')], default='light', max_length=255),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/tbx/services/migrations/0030_subservicepage_remove_fields.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.13 on 2020-11-17 04:57
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("services", "0029_subservice_listingsettings"),
10 | ]
11 |
12 | operations = [
13 | migrations.RemoveField(
14 | model_name="subservicepage", name="show_automatic_blog_listing",
15 | ),
16 | migrations.RemoveField(
17 | model_name="subservicepage", name="show_automatic_case_studies_listing",
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_two-col-text.scss:
--------------------------------------------------------------------------------
1 | .two-col-text {
2 | display: grid;
3 | gap: 30px;
4 |
5 | @include media-query(medium) {
6 | grid-template-columns: repeat(2, 1fr);
7 | row-gap: 30px;
8 | column-gap: 50px;
9 | }
10 |
11 | &__heading {
12 | font-size: map-get($medium-font-sizes, m);
13 | line-height: 34px;
14 | color: var(--color--stone);
15 | margin: 13px 0 10px;
16 | }
17 |
18 | &__content {
19 | font-size: map-get($large-font-sizes, s);
20 | line-height: 31px;
21 | margin: 0;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0141_delete_old_image_models.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.17 on 2021-11-12 15:58
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("torchbox", "0140_update_image_model"),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterUniqueTogether(name="torchboxrendition", unique_together=None,),
14 | migrations.RemoveField(model_name="torchboxrendition", name="image",),
15 | migrations.DeleteModel(name="TorchboxImage",),
16 | migrations.DeleteModel(name="TorchboxRendition",),
17 | ]
18 |
--------------------------------------------------------------------------------
/tbx/work/migrations/0015_workpage_body_word_count.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.16 on 2019-01-22 17:10
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("work", "0014_map_tags_to_related_services"),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name="workpage",
17 | name="body_word_count",
18 | field=models.PositiveIntegerField(editable=False, null=True),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/tbx/work/migrations/0017_listing_summary_not_required.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.16 on 2019-01-22 17:19
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("work", "0016_rename_summary_to_listing_summary"),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name="workpage",
17 | name="listing_summary",
18 | field=models.CharField(blank=True, max_length=255),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/tbx/core/management/commands/test_sentry.py:
--------------------------------------------------------------------------------
1 | from django.core.management.base import BaseCommand
2 |
3 | from sentry_sdk import capture_exception, capture_message
4 |
5 |
6 | class Command(BaseCommand):
7 | """
8 | Sends a message to Sentry to test if it's set up correctly
9 |
10 | To test locally specify the SENTRY_DSN for this command only:
11 | SENTRY_DSN=... ./manage.py test_sentry
12 |
13 | https://github.com/getsentry/sentry-python/issues/367
14 | """
15 |
16 | def handle(self, *args, **options):
17 | capture_message("test message")
18 | capture_exception(Exception("test exception"))
19 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0093_wagtail19_upgrade.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2017-03-20 08:43
3 |
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0092_servicepage_add_logos"),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name="torchboxrendition",
17 | name="focal_point_key",
18 | field=models.CharField(
19 | blank=True, default="", editable=False, max_length=16
20 | ),
21 | ),
22 | ]
23 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/atoms/see-more/see-more.html:
--------------------------------------------------------------------------------
1 | {% if text %}
2 |
3 | {% if fetch_data %}
4 |
{{ text }}
5 | {% else %}
6 | {% if filter_by %}
7 |
{{ text }}
8 | {% else %}
9 |
{{ text }}
10 | {% endif %}
11 | {% endif %}
12 |
13 | {% endif %}
14 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/card/card.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags %}
2 |
15 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0063_auto_20160906_0949.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-09-06 08:49
3 |
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0062_auto_20160905_1151"),
12 | ]
13 |
14 | operations = [
15 | migrations.RemoveField(model_name="aboutpagevalue", name="image",),
16 | migrations.RemoveField(model_name="aboutpagevalue", name="page",),
17 | migrations.RemoveField(model_name="aboutpage", name="values_title",),
18 | migrations.DeleteModel(name="AboutPageValue",),
19 | ]
20 |
--------------------------------------------------------------------------------
/tbx/services/migrations/0017_auto_20190207_1702.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-02-07 17:02
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("services", "0016_auto_20190207_1630"),
10 | ]
11 |
12 | operations = [
13 | migrations.RenameField(
14 | model_name="servicepageprocess", old_name="link_page", new_name="page_link",
15 | ),
16 | migrations.RenameField(
17 | model_name="servicepageprocess",
18 | old_name="link_label",
19 | new_name="page_link_label",
20 | ),
21 | ]
22 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0007_auto_20150326_1142.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 |
4 | from django.db import models, migrations
5 | import wagtail.fields
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0006_auto_20150326_1023"),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name="blogpage",
17 | name="body",
18 | field=wagtail.fields.RichTextField(
19 | verbose_name="body (deprecated. Use streamfield instead)", blank=True
20 | ),
21 | preserve_default=True,
22 | ),
23 | ]
24 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/bustout_block.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags wagtailimages_tags %}
2 |
3 |
4 | {% image value.image fill-1060x655 as bustout_image %}
5 |
6 |
7 |
8 | {{ value.text|richtext }}
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_small-image-with-text.scss:
--------------------------------------------------------------------------------
1 | .small-image-with-text {
2 | margin-bottom: 25px;
3 |
4 | @include media-query(medium) {
5 | display: grid;
6 | grid-template-columns: 80px 1fr;
7 | gap: 25px;
8 | }
9 |
10 | &__image {
11 | margin-bottom: 10px;
12 | max-width: 50px;
13 |
14 | @include media-query(medium) {
15 | margin-bottom: 0;
16 | max-width: 80px;
17 | }
18 | }
19 |
20 | &__title {
21 | font-size: map-get($medium-font-sizes, m);
22 | color: var(--color--stone);
23 | margin: 0 0 5px;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_job-listing.scss:
--------------------------------------------------------------------------------
1 | .job-listing {
2 | position: relative;
3 | background-color: var(--color--white);
4 | padding: ($gutter * 2) 0 $gutter;
5 |
6 | &__image {
7 | position: absolute;
8 | top: 40px;
9 | width: 28vw;
10 | max-width: 380px;
11 |
12 | @include media-query(medium) {
13 | width: 20vw;
14 | }
15 | }
16 |
17 | &__list {
18 | @include container();
19 | padding: calc(0.75 * 28vw + 40px) 0 0 0;
20 |
21 | @include media-query(medium) {
22 | padding: 0 $variable-gutter--medium;
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/tbx/static_src/javascript/components/shards-images.js:
--------------------------------------------------------------------------------
1 | class ShardsImages {
2 | static selector() {
3 | return '[data-shards-hero]';
4 | }
5 |
6 | constructor(node) {
7 | this.node = node;
8 | this.imageTotal = node.dataset.imagetotal;
9 | this.images = node.querySelectorAll('[data-shards-image]');
10 | this.showRandomImage();
11 | }
12 |
13 | showRandomImage() {
14 | const randomNumber = Math.floor(Math.random() * this.imageTotal);
15 | const image = this.images[randomNumber];
16 | image.classList.add('shards__image--visible');
17 | }
18 | }
19 |
20 | export default ShardsImages;
21 |
--------------------------------------------------------------------------------
/tbx/images/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 |
3 | from wagtail.images.models import AbstractImage, AbstractRendition, Image
4 |
5 |
6 | class CustomImage(AbstractImage):
7 | credit = models.CharField(max_length=255, blank=True)
8 |
9 | admin_form_fields = Image.admin_form_fields + ("credit",)
10 |
11 | @property
12 | def credit_text(self):
13 | return self.credit
14 |
15 |
16 | class Rendition(AbstractRendition):
17 | image = models.ForeignKey(
18 | "CustomImage", related_name="renditions", on_delete=models.CASCADE
19 | )
20 |
21 | class Meta:
22 | unique_together = (("image", "filter_spec", "focal_point_key"),)
23 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0027_auto_20160603_1718.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-06-03 16:18
3 |
4 |
5 | from django.db import migrations
6 | import wagtail.fields
7 |
8 |
9 | class Migration(migrations.Migration):
10 |
11 | dependencies = [
12 | ("torchbox", "0026_merge"),
13 | ]
14 |
15 | operations = [
16 | migrations.AlterField(
17 | model_name="blogpage",
18 | name="intro",
19 | field=wagtail.fields.RichTextField(
20 | blank=True,
21 | verbose_name="Intro (used for blog index and Planet Drupal listings)",
22 | ),
23 | ),
24 | ]
25 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0085_add_filter_spec_field.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2017-01-17 16:33
3 |
4 |
5 | from django.db import migrations, models
6 | import django.db.models.deletion
7 |
8 |
9 | class Migration(migrations.Migration):
10 |
11 | dependencies = [
12 | ("torchbox", "0084_homepage_add_editable_strapline"),
13 | ]
14 |
15 | operations = [
16 | migrations.AddField(
17 | model_name="torchboxrendition",
18 | name="filter_spec",
19 | field=models.CharField(
20 | blank=True, db_index=True, default="", max_length=255
21 | ),
22 | ),
23 | ]
24 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/external_link_cta_block.html:
--------------------------------------------------------------------------------
1 |
13 |
14 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0031_blogpage_homepage_color.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-06-17 11:40
3 |
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0030_auto_20160617_1146"),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name="blogpage",
17 | name="homepage_color",
18 | field=models.TextField(
19 | blank=True,
20 | verbose_name="Homepage colour (orange, blue, white) if left blank will display image",
21 | ),
22 | ),
23 | ]
24 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0083_homepage_remove_unused_field.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2017-01-17 13:04
3 |
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0082_auto_20170112_1611"),
12 | ]
13 |
14 | operations = [
15 | migrations.RemoveField(model_name="homepage", name="hero_intro",),
16 | migrations.RemoveField(model_name="homepage", name="hero_video_id",),
17 | migrations.RemoveField(model_name="homepage", name="hero_video_poster_image",),
18 | migrations.RemoveField(model_name="homepage", name="intro_title",),
19 | ]
20 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/contact-slim/contact-slim.html:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/key-points.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | value:
3 | title: Services
4 | heading_for_key_points: 'We help you create digital products and services, fast . And, you can transform your organisation along the way.
'
5 | key_points:
6 | - text: UX Research and Design
7 | linked_page: '#'
8 | - text: Design Sprints
9 | - text: Software Engineering
10 | linked_page: '#'
11 | - text: Wagtail CMS services
12 | - text: Digital marketing
13 | linked_page: '#'
14 | page:
15 | contact:
16 | email_address: willh@torchbox.com
17 | phone_number: +441608811870
18 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/title-block/title-block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | item:
3 | title: Example title
4 |
5 | tags:
6 | - name: Culture
7 | slug: culture
8 | - name: Digital products
9 | slug: digital-products
10 | - name: Wagtail
11 | slug: wagtail
12 | - name: Digital Marketing
13 | slug: digital-marketing
14 | - name: PPC
15 | slug: ppc
16 | - name: SEO
17 | slug: seo
18 | - name: Social media
19 | slug: social-media
20 | - name: Data
21 | slug: data
22 | - name: Google Ad Grants
23 | slug: google-ad-grants
24 |
25 | tags:
26 | pageurl:
27 | item as index:
28 | raw: '#'
29 |
--------------------------------------------------------------------------------
/tbx/people/migrations/0013_culturepage_strapline_visible.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-03-20 15:02
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("people", "0012_auto_20190316_1641"),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name="culturepage",
15 | name="strapline_visible",
16 | field=models.BooleanField(
17 | default=False,
18 | help_text="Hide strapline visually but leave it readable by screen readers.",
19 | ),
20 | preserve_default=False,
21 | ),
22 | ]
23 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/blocks/impact_report_heading_block.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags wagtailimages_tags static %}
2 |
3 |
4 | {% image value.image fill-1792x597 class="report-section__image" alt="" %}
5 |
6 |
7 |
8 |
9 |
10 |
11 | {{ value.short_heading }}
12 |
13 |
14 |
{{ value.heading|richtext }}
15 |
16 |
17 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/pages/team/team_detail.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | page:
3 | biography: 'Colin has had an illustrious career in international logistics. His favourite colours are black and grey but, Colin is a colourful person and loves exploring culture, the wilderness and dark nightclubs.
'
4 | get_verbose_name: person-page
5 | intro: 'Colin is a Red Hat Certified Engineer and uses his expert knowledge to implement and maintain technical infrastructure.
'
6 | role: Head of Awesome
7 | title: Colin Knowles
8 |
9 | tags:
10 | image:
11 | page.image width-1280 as image:
12 | target_var: image
13 | raw:
14 | url: '//placekitten.com/1280/1706'
15 |
--------------------------------------------------------------------------------
/tbx/propositions/factories.py:
--------------------------------------------------------------------------------
1 | import factory
2 | from tbx.propositions.models import PropositionPage, SubPropositionPage
3 | from tbx.taxonomy.factories import ServiceFactory
4 | from wagtail_factories import PageFactory
5 |
6 |
7 | class PropositionPageFactory(PageFactory):
8 | title = factory.Faker("text", max_nb_chars=20)
9 | strapline = factory.Faker("sentence")
10 | service = factory.SubFactory(ServiceFactory)
11 |
12 | class Meta:
13 | model = PropositionPage
14 |
15 |
16 | class SubPropositionPageFactory(PageFactory):
17 | title = factory.Faker("text", max_nb_chars=20)
18 | strapline = factory.Faker("sentence")
19 |
20 | class Meta:
21 | model = SubPropositionPage
22 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0027_marketinglandingpagerelatedlink_email_link.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-05-31 15:14
3 |
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0026_merge"),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name="marketinglandingpagerelatedlink",
17 | name="email_link",
18 | field=models.EmailField(
19 | blank=True,
20 | help_text="Enter email address only, without 'mailto:'",
21 | max_length=254,
22 | ),
23 | ),
24 | ]
25 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0065_auto_20160906_1449.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-09-06 13:49
3 |
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0064_aboutpagerelatedlinkbutton"),
12 | ]
13 |
14 | operations = [
15 | migrations.RenameModel(old_name="HomePageClients", new_name="HomePageClient",),
16 | migrations.RenameModel(
17 | old_name="StandardPageClients", new_name="StandardPageClient",
18 | ),
19 | migrations.AlterModelOptions(
20 | name="servicespageservice", options={"ordering": ["sort_order"]},
21 | ),
22 | ]
23 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0154_alter_socialmediasettings_site_name.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 4.2.8 on 2024-03-19 16:21
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("torchbox", "0153_change_minimum_number_for_key_points"),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterField(
14 | model_name="socialmediasettings",
15 | name="site_name",
16 | field=models.CharField(
17 | blank=True,
18 | default="Torchbox",
19 | help_text="Site name, used by Open Graph.",
20 | max_length=255,
21 | ),
22 | ),
23 | ]
24 |
--------------------------------------------------------------------------------
/tbx/people/migrations/0022_auto_20210412_1042.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.17 on 2021-04-12 09:42
2 |
3 | from django.db import migrations, models
4 | import wagtail.fields
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ("people", "0021_valuespagevalue_value_image"),
11 | ]
12 |
13 | operations = [
14 | migrations.AlterField(
15 | model_name="valuespagevalue",
16 | name="heading",
17 | field=models.CharField(max_length=255),
18 | ),
19 | migrations.AlterField(
20 | model_name="valuespagevalue",
21 | name="text",
22 | field=wagtail.fields.RichTextField(blank=True),
23 | ),
24 | ]
25 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_events.scss:
--------------------------------------------------------------------------------
1 | .events {
2 | @include container();
3 |
4 | &__container {
5 | margin: 0 0 ($grid * 4);
6 |
7 | @include media-query(large) {
8 | margin: ($grid * 6) $variable-gutter--small ($grid * 4)
9 | $variable-gutter--medium;
10 | max-width: 700px;
11 | }
12 |
13 | &--empty {
14 | margin: ($grid * 2) 0 ($grid * 4);
15 |
16 | @include media-query(large) {
17 | margin: ($grid * 3) $variable-gutter--small ($grid * 6)
18 | $variable-gutter--medium;
19 | }
20 | }
21 | }
22 |
23 | &__empty {
24 | @include font-size(m);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/navigation/footer-links.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags %}
2 |
15 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0033_homepagehero_colour.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-06-17 14:40
3 |
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0032_jobindexpagejob_job_intro"),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name="homepagehero",
17 | name="colour",
18 | field=models.CharField(
19 | default="",
20 | help_text="Colour of link and background gradient, defaults to blue",
21 | max_length=255,
22 | ),
23 | preserve_default=False,
24 | ),
25 | ]
26 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0069_auto_20160915_1023.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-09-15 09:23
3 |
4 |
5 | from django.db import migrations, models
6 | import wagtail.images.models
7 |
8 |
9 | class Migration(migrations.Migration):
10 |
11 | dependencies = [
12 | ("torchbox", "0068_torchboximage_collection"),
13 | ]
14 |
15 | operations = [
16 | migrations.AlterField(
17 | model_name="torchboxrendition",
18 | name="file",
19 | field=models.ImageField(
20 | height_field="height",
21 | upload_to=wagtail.images.models.get_rendition_upload_to,
22 | width_field="width",
23 | ),
24 | ),
25 | ]
26 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/pages/team/team_listing.html:
--------------------------------------------------------------------------------
1 | {% extends "patterns/base_page.html" %}
2 | {% load wagtailcore_tags wagtailimages_tags static %}
3 |
4 | {% block content %}
5 |
6 | {% include "patterns/molecules/title-block/title-block.html" with title=page.strapline %}
7 |
8 |
9 |
10 |
11 |
12 | {% for member in page.team %}
13 | {% include "patterns/molecules/team-member/team-member.html" with item=member %}
14 | {% endfor %}
15 |
16 |
17 |
18 |
19 |
20 | {% include_block page.call_to_action %}
21 |
22 | {% endblock %}
23 |
--------------------------------------------------------------------------------
/tbx/blog/migrations/0016_blogpage_related_services.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.16 on 2019-01-22 15:10
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 | import modelcluster.fields
7 |
8 |
9 | class Migration(migrations.Migration):
10 |
11 | dependencies = [
12 | ("taxonomy", "0001_initial"),
13 | ("blog", "0015_auto_20190123_1133"),
14 | ]
15 |
16 | operations = [
17 | migrations.AddField(
18 | model_name="blogpage",
19 | name="related_services",
20 | field=modelcluster.fields.ParentalManyToManyField(
21 | related_name="blog_posts", to="taxonomy.Service"
22 | ),
23 | ),
24 | ]
25 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0058_auto_20160831_1239.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-08-31 11:39
3 |
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0057_auto_20160831_1135"),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name="blogpage",
17 | name="colour",
18 | field=models.TextField(
19 | blank=True,
20 | choices=[("orange", "Orange"), ("blue", "Blue"), ("white", "White")],
21 | verbose_name="Listing card colour if left blank will display image",
22 | ),
23 | ),
24 | ]
25 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/_pattern_library_only/README.md:
--------------------------------------------------------------------------------
1 | # Pattern library only templates
2 |
3 | This directory contains templates that we are going to use
4 | only in the pattern library.
5 |
6 | For example, we can have a pattern template for evry Wagtail streamfield
7 | block and one pattern that contains wrapper layout for
8 | all streamfield blocks.
9 |
10 | It doesn't make much sense to render wrapper layout separately,
11 | because it's not visible for a user. Instead we want to render it
12 | with all possible streamfield blocks. To do that we need a temporary
13 | template that will include all possible streamfield blocks.
14 | But we don't want this template to be shown in the pattern listing.
15 | So we put this template here.
16 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/streamfield-example-proposition-page/clients-section-body.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {% include "patterns/molecules/streamfield/blocks/client-logo-block.html" %}
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | {% include "patterns/molecules/streamfield/blocks/pullquote_block.html" with classes="pullquote--slider" %}
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/tbx/services/migrations/0018_auto_20190207_1740.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-02-07 17:40
2 |
3 | from django.db import migrations
4 | import django.db.models.deletion
5 | import modelcluster.fields
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("services", "0017_auto_20190207_1702"),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name="servicepageprocess",
17 | name="page",
18 | field=modelcluster.fields.ParentalKey(
19 | on_delete=django.db.models.deletion.CASCADE,
20 | related_name="processes",
21 | to="services.ServicePage",
22 | ),
23 | ),
24 | ]
25 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0087_auto_20170117_1643.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2017-01-17 16:43
3 |
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0086_fill_filter_spec_field"),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name="torchboxrendition",
17 | name="filter_spec",
18 | field=models.CharField(db_index=True, max_length=255),
19 | ),
20 | migrations.AlterUniqueTogether(
21 | name="torchboxrendition",
22 | unique_together=set([("image", "filter_spec", "focal_point_key")]),
23 | ),
24 | ]
25 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/help-block/help-block.yaml:
--------------------------------------------------------------------------------
1 | context:
2 | contact:
3 | email_address: willh@torchbox.com
4 | phone_number: +441608811870
5 | intro: 'We help you create digital products and services, fast . And, you can transform your organisation along the way.
'
6 | items:
7 | - text: UX Research and Design
8 | - text: Design Sprints
9 | - text: Software Engineering
10 | - text: Wagtail CMS services
11 | - text: Digital marketing
12 | title: Services
13 |
14 | tags:
15 | image:
16 | contact.image fill-100x100 class="avatar__image":
17 | raw: ' '
18 | pageurl:
19 | item.linked_page:
20 | raw: '#'
21 |
--------------------------------------------------------------------------------
/tbx/services/migrations/0029_subservice_listingsettings.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-03-25 16:57
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("services", "0028_services_orderable_fix"),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name="subservicepage",
15 | name="show_automatic_blog_listing",
16 | field=models.BooleanField(default=False),
17 | ),
18 | migrations.AddField(
19 | model_name="subservicepage",
20 | name="show_automatic_case_studies_listing",
21 | field=models.BooleanField(default=False),
22 | ),
23 | ]
24 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_button.scss:
--------------------------------------------------------------------------------
1 | .button {
2 | display: inline-flex;
3 | flex-direction: row;
4 | align-items: center;
5 | justify-content: center;
6 | padding: 12px 18px;
7 | background-color: var(--color--coral);
8 | color: var(--color--white);
9 | font-size: rem(18px);
10 | font-weight: $weight--heavy;
11 | border-radius: 8px;
12 | transition: background-color $transition-quick;
13 | border-bottom: 0;
14 |
15 | &:hover,
16 | &:focus,
17 | &:active {
18 | background-color: var(--color--coral-dark);
19 | color: var(--color--white);
20 | }
21 |
22 | @include media-query('medium') {
23 | font-size: rem(22px);
24 | padding: 16px 24px;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tbx/work/migrations/0013_workpage_related_services.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.16 on 2019-01-22 15:10
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 | import modelcluster.fields
7 |
8 |
9 | class Migration(migrations.Migration):
10 |
11 | dependencies = [
12 | ("taxonomy", "0001_initial"),
13 | ("work", "0012_remove_workpage_intro"),
14 | ]
15 |
16 | operations = [
17 | migrations.AddField(
18 | model_name="workpage",
19 | name="related_services",
20 | field=modelcluster.fields.ParentalManyToManyField(
21 | related_name="case_studies", to="taxonomy.Service"
22 | ),
23 | ),
24 | ]
25 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/organisms/process-block/process-block.html:
--------------------------------------------------------------------------------
1 | {% load wagtailcore_tags %}
2 | {% load wagtailembeds_tags %}
3 |
4 |
5 | {% include "patterns/atoms/section-title/section-title.html" with title=section_title %}
6 |
7 |
8 |
9 | {% for process in processes %}
10 | {% include "patterns/molecules/process-item/process-item.html" with item=process %}
11 | {% endfor %}
12 |
13 |
14 | {% if section_cta %}
15 |
16 | {{ section_cta|richtext }}
17 |
18 | {% endif %}
19 |
20 |
21 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0057_auto_20160831_1135.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-08-31 10:35
3 |
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0056_workpage_visit_the_site"),
12 | ]
13 |
14 | operations = [
15 | migrations.RemoveField(model_name="blogpage", name="homepage_color",),
16 | migrations.AddField(
17 | model_name="blogpage",
18 | name="colour",
19 | field=models.TextField(
20 | blank=True,
21 | verbose_name="Listing card colour (orange, blue, white) if left blank will display image",
22 | ),
23 | ),
24 | ]
25 |
--------------------------------------------------------------------------------
/tbx/services/migrations/0002_auto_20190123_1133.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.0.10 on 2019-01-23 11:33
2 |
3 | from django.db import migrations, models
4 | import django.db.models.deletion
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ("services", "0001_initial"),
11 | ]
12 |
13 | operations = [
14 | migrations.AlterField(
15 | model_name="serviceindexpageservice",
16 | name="link",
17 | field=models.ForeignKey(
18 | blank=True,
19 | null=True,
20 | on_delete=django.db.models.deletion.SET_NULL,
21 | related_name="+",
22 | to="services.ServicePage",
23 | ),
24 | ),
25 | ]
26 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0019_googleadgrantspage_to_address.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-03-10 12:40
3 |
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0018_auto_20160222_1029"),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name="googleadgrantspage",
17 | name="to_address",
18 | field=models.EmailField(
19 | blank=True,
20 | help_text="Optional - form submissions will be emailed to this address",
21 | max_length=254,
22 | verbose_name="to address",
23 | ),
24 | ),
25 | ]
26 |
--------------------------------------------------------------------------------
/tbx/people/migrations/0019_add_key_points_culture_model.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.17 on 2021-03-11 13:05
2 |
3 | from django.db import migrations, models
4 | import wagtail.fields
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ("people", "0018_update_contact"),
11 | ]
12 |
13 | operations = [
14 | migrations.AddField(
15 | model_name="culturepage",
16 | name="heading_for_key_points",
17 | field=wagtail.fields.RichTextField(blank=True),
18 | ),
19 | migrations.AddField(
20 | model_name="culturepage",
21 | name="key_points_section_title",
22 | field=models.TextField(blank=True, default="Benefits"),
23 | ),
24 | ]
25 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/pages/courses/course_landing_page.html:
--------------------------------------------------------------------------------
1 | {% extends "patterns/base_page.html" %}
2 | {% load wagtailcore_tags wagtailimages_tags static %}
3 |
4 | {% block content %}
5 |
6 | {% include "patterns/molecules/hero/hero.html" with title=page.strapline desc=page.intro sub_title=page.sub_title classes='hero--course-landing' %}
7 |
8 |
9 | {% if page.child_page_listing_heading %}
10 |
{{ page.child_page_listing_heading }}
11 | {% endif %}
12 |
13 | {% if subpages %}
14 | {% include "patterns/molecules/course-grid/course-grid.html" with cards=subpages %}
15 | {% endif %}
16 |
17 |
18 | {% endblock %}
19 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0041_auto_20160707_1223.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-07-07 11:23
3 |
4 |
5 | from django.db import migrations
6 | import django.db.models.deletion
7 | import modelcluster.fields
8 |
9 |
10 | class Migration(migrations.Migration):
11 |
12 | dependencies = [
13 | ("torchbox", "0040_auto_20160707_1218"),
14 | ]
15 |
16 | operations = [
17 | migrations.AlterField(
18 | model_name="contactformfield",
19 | name="page",
20 | field=modelcluster.fields.ParentalKey(
21 | on_delete=django.db.models.deletion.CASCADE,
22 | related_name="form_fields",
23 | to="torchbox.Contact",
24 | ),
25 | ),
26 | ]
27 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0020_auto_20160317_0955.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-03-17 09:55
3 |
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0019_googleadgrantspage_to_address"),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name="googleadgrantspage",
17 | name="call_to_action_embed_url",
18 | field=models.URLField(blank=True),
19 | ),
20 | migrations.AlterField(
21 | model_name="googleadgrantspage",
22 | name="call_to_action_title",
23 | field=models.CharField(blank=True, max_length=255),
24 | ),
25 | ]
26 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0059_auto_20160831_1243.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-08-31 11:43
3 |
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("torchbox", "0058_auto_20160831_1239"),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name="blogpage",
17 | name="colour",
18 | field=models.CharField(
19 | blank=True,
20 | choices=[("orange", "Orange"), ("blue", "Blue"), ("white", "White")],
21 | max_length=255,
22 | verbose_name="Listing card colour if left blank will display image",
23 | ),
24 | ),
25 | ]
26 |
--------------------------------------------------------------------------------
/tbx/images/migrations/0005_alter_rendition_file.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 4.2 on 2023-12-12 10:39
2 |
3 | from django.db import migrations
4 | import wagtail.images.models
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ("images", "0004_wagtail42_images"),
11 | ]
12 |
13 | operations = [
14 | migrations.AlterField(
15 | model_name="rendition",
16 | name="file",
17 | field=wagtail.images.models.WagtailImageField(
18 | height_field="height",
19 | storage=wagtail.images.models.get_rendition_storage,
20 | upload_to=wagtail.images.models.get_rendition_upload_to,
21 | width_field="width",
22 | ),
23 | ),
24 | ]
25 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_password-required.scss:
--------------------------------------------------------------------------------
1 | .password-required {
2 | padding: $grid;
3 | display: flex;
4 | flex-direction: column;
5 | align-items: center;
6 | width: 100%;
7 |
8 | &__title {
9 | margin: 0 0 $grid 0;
10 | }
11 |
12 | &__form {
13 | display: flex;
14 | flex-direction: column;
15 | align-items: center;
16 | }
17 |
18 | &__submit-button {
19 | width: max-content;
20 | margin-top: $grid;
21 | margin-bottom: $grid * 4;
22 | padding: 10px 16px;
23 | border: none;
24 | cursor: pointer;
25 |
26 | @include media-query(large) {
27 | margin-top: $grid * 2;
28 | margin-bottom: $grid * 6;
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tbx/taxonomy/migrations/0004_service_preferred_contact.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-02-13 06:23
2 |
3 | from django.db import migrations, models
4 | import django.db.models.deletion
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ("people", "0008_personpage_short_intro"),
11 | ("taxonomy", "0003_service_description"),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name="service",
17 | name="preferred_contact",
18 | field=models.ForeignKey(
19 | blank=True,
20 | null=True,
21 | on_delete=django.db.models.deletion.SET_NULL,
22 | to="people.Contact",
23 | ),
24 | ),
25 | ]
26 |
--------------------------------------------------------------------------------
/tbx/static_src/images/frag-cluster2.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 | Fragment cluster
6 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/tbx/static_src/images/frag-cluster1.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 | Fragment cluster
6 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/tbx/taxonomy/migrations/0005_service_contact_reasons.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-03-16 16:41
2 |
3 | from django.db import migrations, models
4 | import django.db.models.deletion
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ("people", "0012_auto_20190316_1641"),
11 | ("taxonomy", "0004_service_preferred_contact"),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name="service",
17 | name="contact_reasons",
18 | field=models.ForeignKey(
19 | blank=True,
20 | null=True,
21 | on_delete=django.db.models.deletion.SET_NULL,
22 | to="people.ContactReasonsList",
23 | ),
24 | ),
25 | ]
26 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0081_servicespageservice_link.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2017-01-06 10:21
3 |
4 |
5 | from django.db import migrations, models
6 | import django.db.models.deletion
7 |
8 |
9 | class Migration(migrations.Migration):
10 |
11 | dependencies = [
12 | ("torchbox", "0080_auto_20161129_1640"),
13 | ]
14 |
15 | operations = [
16 | migrations.AddField(
17 | model_name="servicespageservice",
18 | name="link",
19 | field=models.ForeignKey(
20 | blank=True,
21 | null=True,
22 | on_delete=django.db.models.deletion.CASCADE,
23 | related_name="+",
24 | to="torchbox.ServicePage",
25 | ),
26 | ),
27 | ]
28 |
--------------------------------------------------------------------------------
/tbx/core/migrations/0115_delete_tshirt_page.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.16 on 2019-01-21 13:53
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ("wagtailredirects", "0006_redirect_increase_max_length"),
12 | ("wagtailforms", "0003_capitalizeverbose"),
13 | ("wagtailcore", "0040_page_draft_title"),
14 | ("torchbox", "0114_remove_standardpage_show_in_play_menu"),
15 | ]
16 |
17 | operations = [
18 | migrations.RemoveField(model_name="tshirtpage", name="main_image",),
19 | migrations.RemoveField(model_name="tshirtpage", name="page_ptr",),
20 | migrations.DeleteModel(name="TshirtPage",),
21 | ]
22 |
--------------------------------------------------------------------------------
/tbx/impact_reports/migrations/0002_alter_impactreportpage_hero_image.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.16 on 2022-12-15 13:56
2 |
3 | from django.db import migrations, models
4 | import django.db.models.deletion
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('images', '0003_alter_customimage_file_hash'),
11 | ('impact_reports', '0001_initial'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name='impactreportpage',
17 | name='hero_image',
18 | field=models.ForeignKey(blank=True, help_text='This is for the illustration only. Use an image with dimensions of 571x700', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='images.customimage'),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | [Link to Ticket]()
2 |
3 | ### Description of Changes Made
4 |
5 | ### How to Test
6 |
7 | ### Screenshots
8 |
9 |
10 | Expand to see more
11 |
12 |
13 |
14 | ### MR Checklist
15 |
16 | - [ ] Add a description of your pull request and instructions for the reviewer to verify your work.
17 | - [ ] If your pull request is for a specific ticket, link to it in the description.
18 | - [ ] Stay on point and keep it small so the merge request can be easily reviewed.
19 | - [ ] Consider adding unit tests, especially for bug fixes. If you don't, tell us why.
20 | - [ ] Tests and linting passes.
21 | - [ ] Consider updating documentation. If you don't, tell us why.
22 | - [ ] If relevant, list the environments / browsers in which you tested your changes.
23 |
--------------------------------------------------------------------------------
/tbx/blog/migrations/0007_rename_related_author_to_authors.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.16 on 2019-01-21 12:49
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 | import django.db.models.deletion
7 | import modelcluster.fields
8 |
9 |
10 | class Migration(migrations.Migration):
11 |
12 | dependencies = [
13 | ("blog", "0006_remove_blogpage_author_left"),
14 | ]
15 |
16 | operations = [
17 | migrations.AlterField(
18 | model_name="blogpageauthor",
19 | name="page",
20 | field=modelcluster.fields.ParentalKey(
21 | on_delete=django.db.models.deletion.CASCADE,
22 | related_name="authors",
23 | to="blog.BlogPage",
24 | ),
25 | ),
26 | ]
27 |
--------------------------------------------------------------------------------
/tbx/blog/migrations/0022_update_image_model.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.17 on 2021-11-12 14:29
2 |
3 | from django.db import migrations, models
4 | import django.db.models.deletion
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ("blog", "0021_update_streamblock_templates"),
11 | ("images", "0003_alter_customimage_file_hash"),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name="blogpage",
17 | name="feed_image",
18 | field=models.ForeignKey(
19 | blank=True,
20 | null=True,
21 | on_delete=django.db.models.deletion.SET_NULL,
22 | related_name="+",
23 | to="images.CustomImage",
24 | ),
25 | ),
26 | ]
27 |
--------------------------------------------------------------------------------
/tbx/settings/test.py:
--------------------------------------------------------------------------------
1 | from .base import * # noqa
2 |
3 | # #############
4 | # General
5 |
6 | # SECRET_KEY is required by Django to start.
7 | SECRET_KEY = "fake_secret_key_to_run_tests" # pragma: allowlist secret
8 |
9 | # Don't redirect to HTTPS in tests.
10 | SECURE_SSL_REDIRECT = False
11 | # Don't send the HSTS header
12 | SECURE_HSTS_SECONDS = 0
13 |
14 | # Don't insist on having run birdbath
15 | BIRDBATH_REQUIRED = False
16 |
17 | # Allow all hosts in tests.
18 | ALLOWED_HOSTS = ["*"]
19 |
20 | # #############
21 | # Performance
22 |
23 | # By default, Django uses a computationally difficult algorithm for passwords hashing.
24 | # We don't need such a strong algorithm in tests, so use MD5
25 | PASSWORD_HASHERS = ["django.contrib.auth.hashers.MD5PasswordHasher"]
26 |
27 | WAGTAILADMIN_BASE_URL = "http://localhost:8000"
28 |
--------------------------------------------------------------------------------
/tbx/static_src/javascript/components/active-nav-item.js:
--------------------------------------------------------------------------------
1 | class ActiveNavItem {
2 | static selector() {
3 | return '[data-menu-item]';
4 | }
5 |
6 | constructor(node) {
7 | this.node = node;
8 | this.pathname = window.location.pathname;
9 | this.pageUrl = this.node.getAttribute('href');
10 | this.isSubnav = this.node.hasAttribute('data-subnav-menu-item');
11 | this.addCurrentClass();
12 | }
13 |
14 | addCurrentClass() {
15 | if (this.pathname.includes(this.pageUrl)) {
16 | if (this.isSubnav) {
17 | this.node.classList.add('subnav__link--active');
18 | } else {
19 | this.node.classList.add('nav-item__link--active');
20 | }
21 | }
22 | }
23 | }
24 |
25 | export default ActiveNavItem;
26 |
--------------------------------------------------------------------------------
/tbx/work/migrations/0007_rename_related_author_to_authors.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.16 on 2019-01-21 12:49
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 | import django.db.models.deletion
7 | import modelcluster.fields
8 |
9 |
10 | class Migration(migrations.Migration):
11 |
12 | dependencies = [
13 | ("work", "0006_remove_workpage_author_left"),
14 | ]
15 |
16 | operations = [
17 | migrations.AlterField(
18 | model_name="workpageauthor",
19 | name="page",
20 | field=modelcluster.fields.ParentalKey(
21 | on_delete=django.db.models.deletion.CASCADE,
22 | related_name="authors",
23 | to="work.WorkPage",
24 | ),
25 | ),
26 | ]
27 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/organisms/related-content/related-content.html:
--------------------------------------------------------------------------------
1 |
2 | {% if title and not hide_title %}
3 | {% include "patterns/atoms/section-title/section-title.html" with title=title %}
4 | {% endif %}
5 |
6 | {% for item in items %}
7 | {% include "patterns/molecules/related-item/related-item.html" with item=item %}
8 | {% endfor %}
9 |
10 | {% if see_more_link %}
11 | {% include "patterns/atoms/see-more/see-more.html" with text=see_more_link_text|default:"See more" link=work_index_page.url filter_by=filter_by %}
12 | {% endif %}
13 |
14 |
--------------------------------------------------------------------------------
/tbx/services/migrations/0003_servicepage_service.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-01-23 15:26
2 |
3 | from django.db import migrations, models
4 | import django.db.models.deletion
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ("taxonomy", "0001_initial"),
11 | ("services", "0002_auto_20190123_1133"),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name="servicepage",
17 | name="service",
18 | field=models.OneToOneField(
19 | blank=True,
20 | help_text="Link to this service in taxonomy",
21 | null=True,
22 | on_delete=django.db.models.deletion.SET_NULL,
23 | to="taxonomy.Service",
24 | ),
25 | ),
26 | ]
27 |
--------------------------------------------------------------------------------
/tbx/static_src/images/tbx-flame.svg:
--------------------------------------------------------------------------------
1 | Flame
2 |
5 |
6 |
--------------------------------------------------------------------------------
/tbx/project_styleguide/templates/patterns/molecules/streamfield/streamfield-example-team.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Colin is a Red Hat Certified Engineer and uses his expert knowledge to implement and maintain technical infrastructure.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
Colin has had an illustrious career in international logistics. His favourite colours are black and grey but, Colin is a colourful person and loves exploring culture, the wilderness and dark nightclubs.
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/tbx/propositions/tests/test_factories.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | from tbx.propositions.factories import (
4 | PropositionPageFactory,
5 | SubPropositionPageFactory,
6 | )
7 |
8 |
9 | class PropositionPageFactoryTestCase(TestCase):
10 | def test_proposition_page_factory(self):
11 | proposition_page = PropositionPageFactory()
12 | self.assertIsNotNone(proposition_page.title)
13 | self.assertIsNotNone(proposition_page.strapline)
14 | self.assertIsNotNone(proposition_page.service)
15 |
16 |
17 | class SubPropositionPageFactoryTestCase(TestCase):
18 | def test_sub_proposition_page_factory(self):
19 | sub_proposition_page = SubPropositionPageFactory()
20 | self.assertIsNotNone(sub_proposition_page.title)
21 | self.assertIsNotNone(sub_proposition_page.strapline)
22 |
--------------------------------------------------------------------------------
/tbx/static_src/javascript/components/sticky-point.js:
--------------------------------------------------------------------------------
1 | import 'intersection-observer';
2 | import scrollama from 'scrollama';
3 |
4 | function scrollamaInit() {
5 | // instantiate the scrollama
6 | const scroller = scrollama();
7 |
8 | // setup the instance, pass callback functions
9 | scroller
10 | .setup({
11 | step: '[data-sticky-point]',
12 | offset: 0,
13 | })
14 | .onStepEnter(() => {
15 | document.body.classList.add('sticky');
16 | })
17 | .onStepExit(() => {
18 | document.body.classList.remove('sticky');
19 | });
20 |
21 | // setup resize event
22 | window.addEventListener('resize', scroller.resize);
23 | }
24 |
25 | if (document.body.contains(document.querySelector('[data-sticky-point]'))) {
26 | scrollamaInit();
27 | }
28 |
--------------------------------------------------------------------------------
/tbx/static_src/sass/components/_sprites-preview-icons.scss:
--------------------------------------------------------------------------------
1 | .sprites-preview-icons {
2 | padding: 40px;
3 | display: flex;
4 | flex-wrap: wrap;
5 |
6 | &__item {
7 | text-align: center;
8 | display: flex;
9 | flex-direction: column;
10 | align-items: center;
11 | margin-right: 0;
12 | margin-bottom: 20px;
13 |
14 | @include media-query(tablet-portrait) {
15 | margin-right: 20px;
16 | }
17 |
18 | &:last-child {
19 | margin-right: 20px;
20 | }
21 | }
22 |
23 | &__icon {
24 | width: 30px;
25 | height: 30px;
26 | color: var(--color--black);
27 | fill: var(--color--black);
28 | }
29 |
30 | &__name {
31 | font-weight: $weight--bold;
32 | padding: $grid;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/tbx/work/migrations/0023_date_data_migration.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.17 on 2021-02-17 14:51
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | def copy_first_published_at_to_date_field(apps, schema_editor):
7 | # We can't import the Person model directly as it may be a newer
8 | # version than this migration expects. We use the historical version.
9 | WorkPage = apps.get_model("work", "workpage")
10 | for workpage in WorkPage.objects.all():
11 | if workpage.date is None:
12 | workpage.date = workpage.first_published_at
13 | workpage.save()
14 |
15 |
16 | class Migration(migrations.Migration):
17 | dependencies = [
18 | ("work", "0022_workpage_date"),
19 | ]
20 |
21 | operations = [
22 | migrations.RunPython(copy_first_published_at_to_date_field),
23 | ]
24 |
--------------------------------------------------------------------------------
/tbx/people/migrations/0006_person_index_page_strapline.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-01-24 16:10
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("people", "0005_contact"),
10 | ]
11 |
12 | operations = [
13 | migrations.RemoveField(model_name="personindexpage", name="intro",),
14 | migrations.RemoveField(
15 | model_name="personindexpage", name="senior_management_intro",
16 | ),
17 | migrations.RemoveField(model_name="personindexpage", name="team_intro",),
18 | migrations.AddField(
19 | model_name="personindexpage",
20 | name="strapline",
21 | field=models.CharField(default="", max_length=255),
22 | preserve_default=False,
23 | ),
24 | ]
25 |
--------------------------------------------------------------------------------
/tbx/people/migrations/0021_valuespagevalue_value_image.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.17 on 2021-04-09 15:51
2 |
3 | from django.db import migrations, models
4 | import django.db.models.deletion
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ("torchbox", "0134_remove_googleadgrantspage_and_related_models"),
11 | ("people", "0020_valuespagevalue"),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name="valuespagevalue",
17 | name="value_image",
18 | field=models.ForeignKey(
19 | blank=True,
20 | null=True,
21 | on_delete=django.db.models.deletion.SET_NULL,
22 | related_name="+",
23 | to="torchbox.TorchboxImage",
24 | ),
25 | ),
26 | ]
27 |
--------------------------------------------------------------------------------