├── .eslintrc ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CODING_STANDARDS.md ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md ├── LICENSE ├── README.md ├── bin └── lorem.js ├── config ├── default.js ├── development.js └── test.js ├── docs ├── button-arrows.png ├── cms.navigation.md ├── lackey-logo-x2.png ├── lackey-logo.png └── logo-spiral@2x.png ├── gulp └── index.js ├── gulpfile.js ├── lib ├── configuration │ └── index.js ├── datasources │ └── index.js ├── generator │ └── index.js ├── index.js ├── mailer │ └── index.js ├── server │ ├── express.js │ ├── index.js │ ├── init │ │ ├── api.js │ │ ├── basics.js │ │ ├── crud.js │ │ ├── envvars.js │ │ ├── errors.js │ │ ├── format.js │ │ ├── locale.js │ │ ├── logger.js │ │ ├── rest.js │ │ ├── static.js │ │ ├── uncap.js │ │ └── views.js │ ├── module-loader.js │ └── start.js ├── sitemap │ └── index.js └── utils │ ├── bindable.js │ ├── clear.js │ ├── cli.js │ └── index.js ├── modules ├── README.md ├── analytics │ ├── client │ │ ├── js │ │ │ ├── charts.js │ │ │ └── index.js │ │ └── scss │ │ │ └── charts.scss │ ├── index.js │ ├── module.yml │ ├── server │ │ ├── controllers │ │ │ ├── api.js │ │ │ └── dashboard.js │ │ ├── lib │ │ │ ├── collector.js │ │ │ └── dust │ │ │ │ └── filter.js │ │ ├── routes │ │ │ └── api.js │ │ └── views │ │ │ ├── dashboard.dust │ │ │ └── tableview.dust │ └── test │ │ └── server │ │ └── lib │ │ └── collector.js ├── cms │ ├── client │ │ ├── img │ │ │ ├── blocks │ │ │ │ ├── copy.png │ │ │ │ ├── image.png │ │ │ │ ├── media-copy-hero.png │ │ │ │ ├── media-copy.png │ │ │ │ ├── media-triple.png │ │ │ │ ├── media.png │ │ │ │ ├── quote.png │ │ │ │ ├── related-content.png │ │ │ │ ├── select-arrow.png │ │ │ │ └── text.png │ │ │ └── svg │ │ │ │ ├── 3-images.svg │ │ │ │ ├── application.svg │ │ │ │ ├── arrow-left.svg │ │ │ │ ├── arrow-right.svg │ │ │ │ ├── article.svg │ │ │ │ ├── bin-filled.svg │ │ │ │ ├── bin.svg │ │ │ │ ├── block │ │ │ │ ├── 4-items-title.svg │ │ │ │ ├── 4-items.svg │ │ │ │ ├── accordion.svg │ │ │ │ ├── animation.svg │ │ │ │ ├── article-title.svg │ │ │ │ ├── asset.svg │ │ │ │ ├── contact.svg │ │ │ │ ├── cv-form.svg │ │ │ │ ├── double-col-bullets.svg │ │ │ │ ├── double-col.svg │ │ │ │ ├── lock.svg │ │ │ │ ├── logos.svg │ │ │ │ ├── media-copy.svg │ │ │ │ ├── newsletter.svg │ │ │ │ ├── person.svg │ │ │ │ ├── section-header.svg │ │ │ │ ├── title-background.svg │ │ │ │ ├── title-copy.svg │ │ │ │ ├── title-cta.svg │ │ │ │ ├── title-sub-copy.svg │ │ │ │ ├── title.svg │ │ │ │ ├── triple-cards-cta.svg │ │ │ │ └── triple-cards.svg │ │ │ │ ├── blog-header.svg │ │ │ │ ├── carousel.svg │ │ │ │ ├── close.svg │ │ │ │ ├── cog.svg │ │ │ │ ├── copy-image.svg │ │ │ │ ├── copy.svg │ │ │ │ ├── down-arrow.svg │ │ │ │ ├── envelope.svg │ │ │ │ ├── eye-filled.svg │ │ │ │ ├── eye.svg │ │ │ │ ├── feature-row.svg │ │ │ │ ├── file.svg │ │ │ │ ├── footer.svg │ │ │ │ ├── form.svg │ │ │ │ ├── header.svg │ │ │ │ ├── hub.svg │ │ │ │ ├── image-copy.svg │ │ │ │ ├── image.svg │ │ │ │ ├── lock.svg │ │ │ │ ├── module.svg │ │ │ │ ├── overflow.svg │ │ │ │ ├── pdf.svg │ │ │ │ ├── plus.svg │ │ │ │ ├── preview.svg │ │ │ │ ├── quote.svg │ │ │ │ ├── share.svg │ │ │ │ ├── swirl.svg │ │ │ │ ├── tags.svg │ │ │ │ ├── ui │ │ │ │ ├── account.svg │ │ │ │ ├── add-block.svg │ │ │ │ ├── dashboard │ │ │ │ │ ├── analytics.svg │ │ │ │ │ ├── content.svg │ │ │ │ │ ├── homepage.svg │ │ │ │ │ ├── media.svg │ │ │ │ │ ├── tags.svg │ │ │ │ │ └── users.svg │ │ │ │ ├── editor │ │ │ │ │ ├── format-bold.svg │ │ │ │ │ ├── format-clear.svg │ │ │ │ │ ├── format-italic.svg │ │ │ │ │ ├── format-list-bulleted.svg │ │ │ │ │ ├── format-list-numbered.svg │ │ │ │ │ ├── format-quote.svg │ │ │ │ │ ├── format-underline.svg │ │ │ │ │ ├── insert-attachment.svg │ │ │ │ │ └── insert-link.svg │ │ │ │ └── settings │ │ │ │ │ ├── add.svg │ │ │ │ │ ├── blocks.svg │ │ │ │ │ ├── changes.svg │ │ │ │ │ ├── dashboard.svg │ │ │ │ │ ├── settings.svg │ │ │ │ │ ├── tags.svg │ │ │ │ │ └── views.svg │ │ │ │ ├── video.svg │ │ │ │ ├── view-thumb.svg │ │ │ │ └── youtube.svg │ │ ├── js │ │ │ ├── block-editor.js │ │ │ ├── context.js │ │ │ ├── controls │ │ │ │ └── autocomplete.js │ │ │ ├── emit.js │ │ │ ├── emitter.js │ │ │ ├── galleryhref.js │ │ │ ├── growl.js │ │ │ ├── header.js │ │ │ ├── iframe.js │ │ │ ├── iframe.resolve.js │ │ │ ├── language.js │ │ │ ├── manager │ │ │ │ ├── article.picker.ui.js │ │ │ │ ├── block.picker.ui.js │ │ │ │ ├── change.ui.js │ │ │ │ ├── datetime.picker.ui.js │ │ │ │ ├── dummy.js │ │ │ │ ├── gallery.ui.js │ │ │ │ ├── index.js │ │ │ │ ├── media.js │ │ │ │ ├── picker.ui.js │ │ │ │ ├── repository.js │ │ │ │ ├── role.picker.ui.js │ │ │ │ ├── sources.editor.ui.js │ │ │ │ ├── stack.js │ │ │ │ ├── structure.ui.js │ │ │ │ ├── taxonomy.picker.ui.js │ │ │ │ ├── user.dropdown.js │ │ │ │ └── user.picker.ui.js │ │ │ ├── media.js │ │ │ ├── new-media.js │ │ │ ├── new-page.js │ │ │ ├── new-user-password.js │ │ │ ├── new-user.js │ │ │ ├── page.js │ │ │ ├── pages.js │ │ │ ├── preview.js │ │ │ ├── profile.js │ │ │ ├── table.js │ │ │ ├── view.js │ │ │ └── wysiwyg.js │ │ ├── scss │ │ │ ├── _calendar.scss │ │ │ ├── _content-gallery.scss │ │ │ ├── _fonts.scss │ │ │ ├── _partials │ │ │ │ ├── _account-details.scss │ │ │ │ ├── _anonymous.scss │ │ │ │ ├── _autocomplete.scss │ │ │ │ ├── _blocks.scss │ │ │ │ ├── _content-filter.scss │ │ │ │ ├── _context-content.scss │ │ │ │ ├── _context-media.scss │ │ │ │ ├── _context-tag.scss │ │ │ │ ├── _context-user.scss │ │ │ │ ├── _create-page.scss │ │ │ │ ├── _diff.scss │ │ │ │ ├── _growl.scss │ │ │ │ ├── _header.scss │ │ │ │ ├── _login.scss │ │ │ │ ├── _menu.scss │ │ │ │ ├── _overlay.scss │ │ │ │ ├── _settings.scss │ │ │ │ ├── _sidebar.scss │ │ │ │ ├── _structure.scss │ │ │ │ ├── _structure │ │ │ │ │ └── _main.scss │ │ │ │ ├── _table-header.scss │ │ │ │ ├── _tags.scss │ │ │ │ ├── _toolTip.scss │ │ │ │ ├── _treeview.scss │ │ │ │ └── image-manager │ │ │ │ │ └── _main.scss │ │ │ ├── _switch.scss │ │ │ ├── _typography.scss │ │ │ ├── _vars.scss │ │ │ ├── base.scss │ │ │ ├── block-editor.scss │ │ │ ├── media.scss │ │ │ ├── settings.scss │ │ │ ├── table.scss │ │ │ └── wysiwyg.scss │ │ └── views │ │ │ ├── article-picker.dust │ │ │ ├── block-picker.dust │ │ │ ├── calendar.dust │ │ │ ├── datetime-picker.dust │ │ │ ├── gallery.dust │ │ │ ├── imagelist.dust │ │ │ ├── properties.dust │ │ │ ├── role-picker.dust │ │ │ ├── settings.dust │ │ │ ├── source-editor.dust │ │ │ ├── sources.dust │ │ │ ├── structure │ │ │ ├── articles.dust │ │ │ ├── blocks.dust │ │ │ ├── dimensions.dust │ │ │ ├── item.dust │ │ │ ├── sections.dust │ │ │ ├── taxonomies.dust │ │ │ ├── taxonomy.dust │ │ │ └── users.dust │ │ │ ├── taxonomy-picker.dust │ │ │ └── user-picker.dust │ ├── index.js │ ├── module.yml │ ├── server │ │ ├── controllers │ │ │ ├── activity.js │ │ │ ├── content.js │ │ │ ├── download.js │ │ │ ├── index.js │ │ │ ├── language.js │ │ │ ├── media.js │ │ │ ├── page.js │ │ │ ├── preview.js │ │ │ ├── redirect.js │ │ │ ├── role.js │ │ │ ├── session.js │ │ │ ├── taxonomy-type.js │ │ │ ├── taxonomy.js │ │ │ ├── template.js │ │ │ ├── translation.js │ │ │ └── user.js │ │ ├── lib │ │ │ ├── dust │ │ │ │ ├── acl.js │ │ │ │ ├── acronym.js │ │ │ │ ├── attr.js │ │ │ │ ├── base.js │ │ │ │ ├── block.js │ │ │ │ ├── cms.js │ │ │ │ ├── config.js │ │ │ │ ├── editable.js │ │ │ │ ├── embed.js │ │ │ │ ├── error.js │ │ │ │ ├── filter.js │ │ │ │ ├── has-content.js │ │ │ │ ├── list.js │ │ │ │ ├── media.js │ │ │ │ ├── qs.js │ │ │ │ ├── sort.js │ │ │ │ ├── taxonomy.js │ │ │ │ ├── translate.js │ │ │ │ ├── tweet.js │ │ │ │ └── user-has.js │ │ │ ├── gate.js │ │ │ └── serializer.js │ │ ├── routes │ │ │ └── cms.routes.js │ │ └── views │ │ │ ├── activity-stream.dust │ │ │ ├── contentedit.dust │ │ │ ├── dashboard.dust │ │ │ ├── facebook.dust │ │ │ ├── iframe.dust │ │ │ ├── languages.dust │ │ │ ├── main.dust │ │ │ ├── media-create.dust │ │ │ ├── page-create.dust │ │ │ ├── page.dust │ │ │ ├── partials │ │ │ └── user.dust │ │ │ ├── profile.dust │ │ │ ├── redirect-create.dust │ │ │ ├── tableview.dust │ │ │ ├── templates │ │ │ └── blog.dust │ │ │ ├── user-create.dust │ │ │ ├── user-set-password.dust │ │ │ └── variant.dust │ ├── shared │ │ ├── markdown.js │ │ ├── treeparser.js │ │ ├── video │ │ │ ├── editmode.js │ │ │ └── viewmode.js │ │ ├── vimeo.js │ │ └── youtube.js │ └── test │ │ ├── server │ │ ├── index.test.js │ │ └── lib │ │ │ └── dust │ │ │ ├── acl.test.js │ │ │ ├── acronym.test.js │ │ │ ├── base.test.js │ │ │ ├── qs.test.js │ │ │ └── user-has.js │ │ └── shared │ │ ├── iframerosolve.test.js │ │ └── treeparser.test.js ├── core │ ├── client │ │ ├── img │ │ │ ├── lackey-logo-x2.png │ │ │ ├── lackey-logo.png │ │ │ └── ring.svg │ │ ├── js │ │ │ ├── api.js │ │ │ ├── es5 │ │ │ │ ├── api.js │ │ │ │ ├── growl.js │ │ │ │ ├── template.js │ │ │ │ └── xhr.js │ │ │ ├── index.js │ │ │ ├── modal.js │ │ │ ├── options.js │ │ │ ├── socket.js │ │ │ ├── table.js │ │ │ ├── template.js │ │ │ ├── upload.js │ │ │ └── xhr.js │ │ ├── scss │ │ │ ├── base.scss │ │ │ └── modal.scss │ │ └── views │ │ │ ├── content-modal.dust │ │ │ ├── create-content-modal.dust │ │ │ ├── create-media-modal.dust │ │ │ ├── create-user-modal.dust │ │ │ ├── fullscreen.dust │ │ │ ├── media-modal.dust │ │ │ ├── modal.dust │ │ │ ├── profile-modal.dust │ │ │ └── taxonomy-modal.dust │ ├── index.js │ ├── module.yml │ ├── server │ │ ├── controllers │ │ │ ├── activitylog.js │ │ │ ├── crud.injection.js │ │ │ ├── crud.js │ │ │ └── errors.js │ │ ├── models │ │ │ ├── activity-log │ │ │ │ └── index.js │ │ │ ├── analytics │ │ │ │ └── index.js │ │ │ ├── content │ │ │ │ ├── generator.js │ │ │ │ ├── index.js │ │ │ │ ├── psql │ │ │ │ │ └── ContentACL.sql │ │ │ │ ├── querybuilder.js │ │ │ │ ├── serializer.js │ │ │ │ └── upgrade.js │ │ │ ├── flyweight │ │ │ │ └── index.js │ │ │ ├── knex.js │ │ │ ├── media │ │ │ │ ├── bucket.js │ │ │ │ ├── generator.js │ │ │ │ ├── index.js │ │ │ │ ├── psql │ │ │ │ │ └── MediaACL.sql │ │ │ │ └── sockets.js │ │ │ ├── objection │ │ │ │ └── index.js │ │ │ ├── preview │ │ │ │ └── index.js │ │ │ ├── redirect │ │ │ │ ├── generator.js │ │ │ │ └── index.js │ │ │ ├── role │ │ │ │ ├── generator.js │ │ │ │ └── index.js │ │ │ ├── schema.js │ │ │ ├── session │ │ │ │ └── index.js │ │ │ ├── taggable │ │ │ │ └── index.js │ │ │ ├── taxonomy-type │ │ │ │ ├── generator.js │ │ │ │ └── index.js │ │ │ ├── taxonomy │ │ │ │ ├── generator.js │ │ │ │ └── index.js │ │ │ ├── template │ │ │ │ ├── generator.js │ │ │ │ └── index.js │ │ │ ├── translation │ │ │ │ └── index.js │ │ │ └── user │ │ │ │ ├── generator.js │ │ │ │ └── index.js │ │ ├── routes │ │ │ └── sitemap.js │ │ └── views │ │ │ ├── 404.dust │ │ │ ├── article.dust │ │ │ ├── error.dust │ │ │ ├── main.dust │ │ │ ├── partials │ │ │ └── header.dust │ │ │ ├── sitemap.dust │ │ │ └── yaml.dust │ ├── shared │ │ ├── dust │ │ │ ├── dateTimeFormat.js │ │ │ ├── hashmap.js │ │ │ ├── is.js │ │ │ ├── iterate.js │ │ │ ├── list.js │ │ │ ├── log.js │ │ │ ├── media.js │ │ │ ├── path.js │ │ │ ├── pretty.js │ │ │ ├── split.js │ │ │ ├── switch.js │ │ │ ├── try.js │ │ │ └── youtube.js │ │ └── views │ │ │ ├── content-filter.dust │ │ │ ├── media-filter.dust │ │ │ ├── table-body.dust │ │ │ ├── table-footer.dust │ │ │ ├── table-value.dust │ │ │ ├── table.dust │ │ │ ├── tag-filter.dust │ │ │ └── user-filter.dust │ └── test │ │ └── server │ │ ├── controllers │ │ ├── activitylog.test.js │ │ └── errors.test.js │ │ ├── models │ │ ├── activitylog.test.js │ │ ├── analytics.test.js │ │ ├── complex-serialized.json │ │ ├── complex-toserialize.json │ │ ├── content.test.js │ │ ├── final.json │ │ ├── fromyaml.json │ │ ├── lorem.json │ │ ├── lorem.md.txt │ │ ├── media.test.js │ │ ├── objection.test.js │ │ ├── role.test.js │ │ ├── tableA.json │ │ ├── tableB.json │ │ ├── tableC.json │ │ ├── template.test.js │ │ ├── toyaml.json │ │ ├── user.test.js │ │ └── withimage.txt │ │ └── setup.test.js ├── i18n │ ├── module.json │ └── server │ │ ├── controllers │ │ └── language.js │ │ ├── models │ │ └── language │ │ │ ├── generator.js │ │ │ ├── index.js │ │ │ ├── init-data.json │ │ │ └── knex.js │ │ └── routes │ │ └── index.js └── users │ ├── client │ └── js │ │ ├── account.js │ │ ├── forgot.js │ │ ├── login.js │ │ └── reset-password.js │ ├── index.js │ ├── module.yml │ ├── server │ ├── auth │ │ ├── dynamic-strategies │ │ │ └── github.js │ │ ├── index.js │ │ └── strategies │ │ │ └── local.js │ ├── controllers │ │ ├── account.js │ │ ├── authentication.js │ │ └── login.js │ ├── lib │ │ ├── connect-session-knex │ │ │ └── index.js │ │ └── dust │ │ │ └── role.js │ ├── policies │ │ └── auth.js │ ├── routes │ │ └── login.routes.js │ └── views │ │ ├── account.dust │ │ ├── emails │ │ ├── create-password.dust │ │ └── forgot-password.dust │ │ ├── forgot-password.dust │ │ ├── login.dust │ │ ├── preview.dust │ │ ├── session.dust │ │ └── set-password.dust │ ├── shared │ └── views │ │ └── identities.dust │ └── test │ └── server │ ├── auth │ ├── auth.test.js │ └── strategies │ │ ├── github.test.js │ │ └── local.test.js │ ├── controllers │ └── login.test.js │ └── policies │ └── auth.test.js ├── package.json ├── readme.hbs └── test ├── lib ├── configuration │ └── index.test.js ├── generator │ └── index.test.js ├── mailer │ └── index.test.js ├── server │ ├── express.test.js │ ├── index.test.js │ └── init │ │ ├── api.test.js │ │ ├── basics.test.js │ │ ├── crud.test.js │ │ ├── envvars.test.js │ │ ├── format.test.js │ │ ├── locale.test.js │ │ ├── rest.test.js │ │ └── views.test.js ├── sitemap │ └── index.test.js └── utils │ ├── cli.test.js │ └── utils.test.js └── mockup ├── dbs.js ├── express.js ├── mailtransport.js ├── main.yml ├── project ├── config │ └── test.js ├── git.keep ├── lackey.json └── modules │ └── cms │ └── shared │ └── views │ └── partials │ └── header ├── update.yml ├── xhr.js └── ymls ├── one.yml ├── second.yml └── third.yml /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | test/mockup/project/sites/default/htdocs 4 | test/mockup/project/uploads 5 | *.log 6 | *.lock 7 | .node-version 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "5" 4 | - "4" 5 | #- "4.1" 6 | #- "4.0" 7 | env: 8 | global: 9 | - CXX=g++-4.8 debug='sql,lackey*' 10 | - PGPORT=5433 11 | - PGHOST=localhost 12 | - DATABASE_URL=postgres://localhost:5433/lackey-cms-test 13 | addons: 14 | apt: 15 | sources: 16 | - ubuntu-toolchain-r-test 17 | - precise-pgdg-9.5 18 | packages: 19 | - g++-4.8 20 | - postgresql-9.5 21 | - postgresql-contrib-9.5 22 | postgresql: 9.5 23 | before_install: 24 | - $CXX --version 25 | - if [ "$TRAVIS_NODE_VERSION" = "0.8" ]; then npm install -g npm@2.7.3; fi; 26 | 27 | # NPM 28 | before_script: 29 | - sudo cp /etc/postgresql/9.4/main/pg_hba.conf /etc/postgresql/9.5/main/pg_hba.conf 30 | - sudo /etc/init.d/postgresql restart 31 | - psql -U postgres -c 'CREATE DATABASE "lackey-cms-test";' 32 | - npm install -g gulp 33 | script: 'gulp test' 34 | sudo: required 35 | notifications: 36 | slack: enigma-marketing:yfkKsg1TfkVCvECHeeiLzq7Z 37 | # nop 38 | -------------------------------------------------------------------------------- /CODING_STANDARDS.md: -------------------------------------------------------------------------------- 1 | # Coding Standards 2 | 3 | ## JavaScript 4 | 5 | ### const, var, let 6 | 7 | ```javascript 8 | const 9 | a = require('a'), 10 | b = require('b'); 11 | 12 | // or if single 13 | let b = 1; 14 | ``` 15 | 16 | ### Brackets 17 | 18 | ```javascript 19 | function() { // no enter here 20 | // empty line 21 | // ... 22 | } 23 | ``` 24 | 25 | 26 | ### Arrow functions 27 | 28 | ```javascript 29 | 30 | const 31 | a = b => b + 1, 32 | c = (b, d) => b + d, 33 | f = z => { 34 | 35 | console.log(z); 36 | }; 37 | ``` 38 | 39 | ### Chains 40 | 41 | ```javascript 42 | 43 | return Promise 44 | .all(collection 45 | .map(a => a + 1)) 46 | .then(c => doSomething(c)); 47 | 48 | ``` 49 | -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Issue Title 2 | 3 | ## Type 4 | 5 | * Bug / Feature Request / Documentation / Question 6 | 7 | ## Environment 8 | 9 | * Operating System: 10 | * Node version: 11 | * NPM version: 12 | * Version / Commit hash: 13 | 14 | ## Expected behaviour 15 | 16 | ## Actual behaviour 17 | 18 | ## Notes 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2015-2016 Enigma Marketing Services 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License 14 | -------------------------------------------------------------------------------- /config/default.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true */ 2 | /* globals process */ 3 | 'use strict'; 4 | 5 | /* 6 | Copyright 2016 Enigma Marketing Services Limited 7 | 8 | Licensed under the Apache License, Version 2.0 (the 'License'); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | Unless required by applicable law or agreed to in writing, software 15 | distributed under the License is distributed on an 'AS IS' BASIS, 16 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | See the License for the specific language governing permissions and 18 | limitations under the License. 19 | */ 20 | 21 | 22 | module.exports = { 23 | name: 'Lackey CMS Default Config', 24 | datasources: { 25 | pg: { 26 | 'default': { 27 | dsn: 'postgres://localhost/lackey-cms' 28 | } 29 | } 30 | }, 31 | rebuild : { 32 | sass : true 33 | }, 34 | http : { 35 | port : process.env.PORT || 8888 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /config/development.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true */ 2 | 'use strict'; 3 | 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | module.exports = require('./default'); 20 | -------------------------------------------------------------------------------- /config/test.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | 'use strict'; 3 | 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | const _ = require('lodash'); 20 | 21 | module.exports = _.merge({}, require('./default'), { 22 | isTest: true, 23 | name: 'Lackey CMS Default Test Config', 24 | datasources: { 25 | pg: { 26 | 'default': { 27 | dsn: process.env.CI ? 'postgres://localhost:5433/lackey-cms-test' : 'postgres://localhost/lackey-cms-test' 28 | } 29 | } 30 | }, 31 | http: { 32 | port: 4444 33 | } 34 | }); 35 | -------------------------------------------------------------------------------- /docs/button-arrows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getlackey/lackey-cms/42e75b5f33d92c1cb98dee1067045942ce64f7f3/docs/button-arrows.png -------------------------------------------------------------------------------- /docs/cms.navigation.md: -------------------------------------------------------------------------------- 1 | # Navigation draft 2 | 3 | * Header 4 | * Lackey Icon -> Dashboard 5 | * Page -> Sidebar menu 6 | * Meta 7 | * Author 8 | * Created date 9 | * ... 10 | * Views 11 | * View as -> picker 12 | * Variants -> picker 13 | * Language -> picker 14 | * State -> picker (once supported) 15 | * Tags & Privacy 16 | * \[Tag Group\] -> number of selected on side, picker with checkboxes and create 17 | * Overview - shows all including inhreited from template 18 | * Blocks (to kill later) 19 | * Diff 20 | * Layout / Content toggle 21 | * Publish 22 | * Published / Draft toggle 23 | * Schedule -> Date picker 24 | * Tags & Privacy -> Tags & Privacy ^ 25 | * User -> Dropdown 26 | * Profile 27 | * Logout 28 | 29 | For block menu Page is replicated 30 | -------------------------------------------------------------------------------- /docs/lackey-logo-x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getlackey/lackey-cms/42e75b5f33d92c1cb98dee1067045942ce64f7f3/docs/lackey-logo-x2.png -------------------------------------------------------------------------------- /docs/lackey-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getlackey/lackey-cms/42e75b5f33d92c1cb98dee1067045942ce64f7f3/docs/lackey-logo.png -------------------------------------------------------------------------------- /docs/logo-spiral@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getlackey/lackey-cms/42e75b5f33d92c1cb98dee1067045942ce64f7f3/docs/logo-spiral@2x.png -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | /* jslint esnext:true, node:true */ 2 | 'use strict'; 3 | 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | /** 21 | * @module lackey-cms 22 | * @description Lackey CMS 23 | */ 24 | module.exports = { 25 | /** 26 | * @link lackey-cms/utils 27 | */ 28 | utils: require('./utils'), 29 | /** 30 | * @link lackey-cms/utils/cli 31 | */ 32 | cli: require('./utils/cli'), 33 | /** 34 | * @link lackey-cms/server 35 | */ 36 | server: require('./server'), 37 | /** 38 | * @link lackey-cms/datasources 39 | */ 40 | datasources: require('./datasources'), 41 | /** 42 | * @link lackey-cms/configuration 43 | */ 44 | configuration: require('./configuration'), 45 | /** 46 | * @link lackey-cms/sitemap 47 | */ 48 | sitemap: require('./sitemap'), 49 | /** 50 | * @link lackey-cms/generator 51 | */ 52 | generator: require('./generator'), 53 | /** 54 | * @link lackey-cms/mailer 55 | */ 56 | mailer: require('./mailer'), 57 | /** 58 | * @link lackey-cms/server/module-loader 59 | */ 60 | loader: require('./server/module-loader') 61 | }; 62 | -------------------------------------------------------------------------------- /lib/server/init/api.js: -------------------------------------------------------------------------------- 1 | /*jslint node:true, nomen:true, unparam:true, esnext:true */ 2 | 'use strict'; 3 | 4 | /* 5 | Copyright 2015 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | 21 | const _ = require('lodash'); 22 | 23 | function serialize(data) { 24 | if (Array.isArray(data)) { 25 | return data.map(serialize); 26 | } else if (_.isObject(data) && data.toJSON) { 27 | return data.toJSON(); 28 | } else { 29 | return data; 30 | } 31 | } 32 | 33 | module.exports = function (server) { 34 | server.use((req, res, next) => { 35 | res.api = (result) => { 36 | let data = serialize(result); 37 | res.header('Content-Type', 'application/json'); 38 | res.send(data, 'json'); 39 | }; 40 | res.yaml = (result) => { 41 | res.header('Content-Type', 'text/x-yaml'); 42 | var data = serialize(result, true); 43 | res.send(data, 'yaml'); 44 | }; 45 | next(); 46 | }); 47 | 48 | }; 49 | -------------------------------------------------------------------------------- /lib/server/init/errors.js: -------------------------------------------------------------------------------- 1 | /*jslint node:true, nomen:true, unparam:true, esnext:true */ 2 | 'use strict'; 3 | 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | 21 | const errors = require('common-errors'), 22 | SCli = require('../../utils/cli'); 23 | 24 | module.exports = (server) => { 25 | 26 | SCli.debug('lackey-cms/server/init/errors', 'Setting up'); 27 | 28 | // If we got to this point there was no handler for this request 29 | server.use(module.exports.notFound); 30 | 31 | // Just in Case... Catch all! 32 | server.use(errors.middleware.crashProtector()); 33 | }; 34 | /* istanbul ignore next : external */ 35 | module.exports.notFound = function (req, res, next) { 36 | next(new errors.NotFoundError(req.originalUrl)); 37 | }; 38 | -------------------------------------------------------------------------------- /lib/server/init/logger.js: -------------------------------------------------------------------------------- 1 | /*jslint node:true, nomen:true, esnext:true */ 2 | 'use strict'; 3 | 4 | /* 5 | Copyright 2015 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | 21 | const logger = require('express-bunyan-logger'), 22 | PrettyStream = require('bunyan-prettystream'), 23 | SCli = require('../../utils/cli'); 24 | 25 | module.exports = function (server, config) { 26 | 27 | SCli.debug('lackey-cms/server/init/logger', 'Setting up'); 28 | 29 | let prettyStdOut = new PrettyStream(); 30 | prettyStdOut.pipe(process.stdout); 31 | 32 | if (!process.env.NO_HTTP_DEBUG) { 33 | /* istanbul ignore next */ 34 | server.use(logger({ 35 | name: 'HTTP ' + config.get('name'), 36 | streams: [{ 37 | level: 'debug', 38 | type: 'raw', 39 | stream: prettyStdOut 40 | }] 41 | })); 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /lib/server/init/static.js: -------------------------------------------------------------------------------- 1 | /*jslint node:true, nomen:true, esnext:true */ 2 | 'use strict'; 3 | 4 | /* 5 | Copyright 2015 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | 21 | let path = require('path'), 22 | express = require('express'), 23 | SUtils = require('../../utils'), 24 | SCli = require('../../utils/cli'); 25 | 26 | module.exports = function (server) { 27 | 28 | SCli.debug('lackey-cms/server/init/static', 'Setting up'); 29 | 30 | var docroot = path.join(SUtils.getProjectPath() + '/htdocs'); 31 | 32 | server.use(express.static(docroot, { 33 | redirect: false 34 | })); 35 | server.use('/uploads', express.static(SUtils.getProjectPath() + 'uploads', { 36 | redirect: false 37 | })); 38 | }; 39 | -------------------------------------------------------------------------------- /lib/server/init/uncap.js: -------------------------------------------------------------------------------- 1 | /*jslint node:true, nomen:true, unparam:true, esnext:true */ 2 | 'use strict'; 3 | 4 | /* 5 | Copyright 2015 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | module.exports = function (server) { 21 | server.use((req, res, next) => { 22 | var url = req._parsedUrl; 23 | 24 | if (/[A-Z]/.test(url.pathname)) { 25 | if (url.search === null) { 26 | url.search = ''; 27 | } 28 | res.redirect(301, url.pathname.toLowerCase() + url.search); 29 | } else { 30 | next(); 31 | } 32 | }); 33 | }; 34 | -------------------------------------------------------------------------------- /lib/server/start.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | 'use strict'; 3 | 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | if (!global.LACKEY_PATH) { 21 | /* istanbul ignore next */ 22 | global.LACKEY_PATH = process.env.LACKEY_PATH || __dirname + '/..'; 23 | } 24 | 25 | /* istanbul ignore next */ 26 | let server = require('./index'), 27 | SCli = require('../utils/cli'); 28 | /* istanbul ignore next */ 29 | server({ 30 | stage: process.env.NODE_ENV || 'development' 31 | }) 32 | .then((instance) => { 33 | return instance.init(); 34 | }, (error) => { 35 | SCli.error(error); 36 | }); 37 | -------------------------------------------------------------------------------- /lib/sitemap/index.js: -------------------------------------------------------------------------------- 1 | /* jslint esnext:true, node:true */ 2 | 'use strict'; 3 | 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | /** 21 | * @module lackey-cms/sitemap 22 | */ 23 | 24 | let cache = [], 25 | sources = []; 26 | 27 | module.exports = { 28 | flush: () => { 29 | sources = []; 30 | }, 31 | addSource: source => sources.push(source), 32 | refresh: () => { 33 | return Promise 34 | .all(sources.map(source => source())) 35 | .then(results => { 36 | let merged = []; 37 | results 38 | .forEach(result => { 39 | merged = merged.concat(result); 40 | return merged; 41 | }); 42 | cache = merged; 43 | return merged; 44 | }); 45 | }, 46 | getCached: () => { 47 | return cache; 48 | } 49 | }; 50 | -------------------------------------------------------------------------------- /lib/utils/bindable.js: -------------------------------------------------------------------------------- 1 | /* eslint no-underscore-dangle:0, no-process-exit:0 */ 2 | /* jslint node:true, esnext:true */ 3 | 'use strict'; 4 | 5 | /* 6 | Copyright 2016 Enigma Marketing Services Limited 7 | 8 | Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | Unless required by applicable law or agreed to in writing, software 15 | distributed under the License is distributed on an "AS IS" BASIS, 16 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | See the License for the specific language governing permissions and 18 | limitations under the License. 19 | */ 20 | 21 | const SUtils = require('./index'); 22 | 23 | /** 24 | * @class 25 | * This is super awesome class that bind context of promise, arrize arguments and more 26 | */ 27 | class Bindable { 28 | 29 | /** 30 | * Bind function to context 31 | * @param {function} fn 32 | * @param {array|null} args 33 | * @returns {function} 34 | */ 35 | bind(fn, args) { 36 | let self = this; 37 | return function () { 38 | let injectedArgs = SUtils.asArr(arguments); 39 | if (args && args.length) { 40 | injectedArgs = args.concat(injectedArgs); 41 | } 42 | return fn.apply(self, injectedArgs); 43 | }; 44 | } 45 | 46 | } 47 | 48 | module.exports = Bindable; 49 | -------------------------------------------------------------------------------- /lib/utils/clear.js: -------------------------------------------------------------------------------- 1 | /* eslint strict:0 no-octal-escape:0 */ 2 | /* jslint node:true */ 3 | module.exports = '\033[2J\033[0f'; 4 | -------------------------------------------------------------------------------- /modules/analytics/client/js/index.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, browser:true */ 2 | 'use strict'; 3 | 4 | var 5 | xhr = require('core/client/js/es5/xhr'), 6 | reload = function () { 7 | 8 | Array.prototype.slice 9 | .apply(document.body.querySelectorAll('[data-lky-analytics]')) 10 | .forEach(function (element) { 11 | var 12 | config = element.getAttribute('data-lky-analytics'); 13 | if (config) { 14 | config 15 | .split(';') 16 | .forEach(function (entry) { 17 | var pair = entry.split('|'); 18 | element.addEventListener(pair[0], function () { 19 | var base = document.head.querySelector('base').getAttribute('href').toString().replace(/(\/|)$/, '/'); 20 | xhr.get(base + 'stat/' + encodeURIComponent((pair[1] || element.href))); 21 | }, true); 22 | }); 23 | } 24 | element.removeAttribute('data-lky-analytics'); 25 | }); 26 | 27 | setTimeout(1000 * 60, reload); 28 | 29 | }; 30 | 31 | reload(); 32 | -------------------------------------------------------------------------------- /modules/analytics/client/scss/charts.scss: -------------------------------------------------------------------------------- 1 | @import "chartist/dist/scss/chartist.scss"; 2 | 3 | .ct-chart { 4 | width : 50%; 5 | max-height: 300px; 6 | margin: auto; 7 | } 8 | -------------------------------------------------------------------------------- /modules/analytics/index.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | /* globals LACKEY_PATH */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | const 21 | collector = require('./server/lib/collector'), 22 | filter = require('./server/lib/dust/filter'); 23 | /** 24 | * @param {lackey-cms/lib/server/Server} instance 25 | */ 26 | module.exports = (instance) => { 27 | 28 | instance.addDustHelper(filter); 29 | 30 | instance.addMiddleware((server) => { 31 | server.use((req, res, next) => { 32 | if(req.method === 'GET') { 33 | collector.log('impression:' + req.path); 34 | } 35 | next(); 36 | }); 37 | }); 38 | 39 | }; 40 | -------------------------------------------------------------------------------- /modules/analytics/module.yml: -------------------------------------------------------------------------------- 1 | name : 'Lackey - Analytics' 2 | 3 | require: 4 | #- 'cms/core' 5 | 6 | init: 7 | 8 | routes: 9 | /cms/analytics: 10 | get: 11 | controller: cms/analytics/server/controllers/dashboard#index 12 | ACLHelper: admin 13 | # ACL - for future 14 | 15 | /cms/analytics/:metricIndex: 16 | get: 17 | controller: cms/analytics/server/controllers/dashboard#table 18 | inject: 19 | - cms/core/server/models/analytics 20 | ACLHelper: admin 21 | routeParams: 22 | metricIndex: 23 | field: metricIndex 24 | -------------------------------------------------------------------------------- /modules/analytics/server/lib/collector.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | /* globals LACKEY_PATH */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | const 21 | SUtils = require(LACKEY_PATH).utils, 22 | model = SUtils.cmsMod('core').model('analytics'); 23 | 24 | /** 25 | * @class 26 | * @name AnaltyicsCollector 27 | */ 28 | class AnaltyicsCollector { 29 | 30 | /** 31 | * Logs event in analtycis 32 | * @param {string} metric 33 | * @param {number|undefined} [value=1] 34 | */ 35 | static log(metric, value) { 36 | return model.then(Model => Model.inc(metric, value || 1)); 37 | } 38 | } 39 | 40 | module.exports = AnaltyicsCollector; 41 | -------------------------------------------------------------------------------- /modules/analytics/server/routes/api.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | /* globals LACKEY_PATH */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | module.exports = (server) => { 21 | 22 | return require('../controllers/api') 23 | .then( 24 | APIController => { 25 | 26 | server.route('/stat/:metric').get(APIController.log); 27 | server.route('/stat/:metric/:metricValue').get(APIController.log); 28 | 29 | 30 | 31 | server.param('metric', (req, res, next, id) => { 32 | req.metric = id; 33 | next(); 34 | }); 35 | 36 | server.param('metricValue', (req, res, next, id) => { 37 | req.metricValue = id; 38 | next(); 39 | }); 40 | 41 | }); 42 | }; 43 | -------------------------------------------------------------------------------- /modules/analytics/server/views/dashboard.dust: -------------------------------------------------------------------------------- 1 | {>"cms/cms/main"/} 2 | 3 | { 5 |

Analytics

6 | {#data.metrics} 7 |
8 |

{name}

9 |
10 | Learn More 11 |
12 | {/data.metrics} 13 |
14 | 15 | {/body} 16 | -------------------------------------------------------------------------------- /modules/cms/client/img/blocks/copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getlackey/lackey-cms/42e75b5f33d92c1cb98dee1067045942ce64f7f3/modules/cms/client/img/blocks/copy.png -------------------------------------------------------------------------------- /modules/cms/client/img/blocks/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getlackey/lackey-cms/42e75b5f33d92c1cb98dee1067045942ce64f7f3/modules/cms/client/img/blocks/image.png -------------------------------------------------------------------------------- /modules/cms/client/img/blocks/media-copy-hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getlackey/lackey-cms/42e75b5f33d92c1cb98dee1067045942ce64f7f3/modules/cms/client/img/blocks/media-copy-hero.png -------------------------------------------------------------------------------- /modules/cms/client/img/blocks/media-copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getlackey/lackey-cms/42e75b5f33d92c1cb98dee1067045942ce64f7f3/modules/cms/client/img/blocks/media-copy.png -------------------------------------------------------------------------------- /modules/cms/client/img/blocks/media-triple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getlackey/lackey-cms/42e75b5f33d92c1cb98dee1067045942ce64f7f3/modules/cms/client/img/blocks/media-triple.png -------------------------------------------------------------------------------- /modules/cms/client/img/blocks/media.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getlackey/lackey-cms/42e75b5f33d92c1cb98dee1067045942ce64f7f3/modules/cms/client/img/blocks/media.png -------------------------------------------------------------------------------- /modules/cms/client/img/blocks/quote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getlackey/lackey-cms/42e75b5f33d92c1cb98dee1067045942ce64f7f3/modules/cms/client/img/blocks/quote.png -------------------------------------------------------------------------------- /modules/cms/client/img/blocks/related-content.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getlackey/lackey-cms/42e75b5f33d92c1cb98dee1067045942ce64f7f3/modules/cms/client/img/blocks/related-content.png -------------------------------------------------------------------------------- /modules/cms/client/img/blocks/select-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getlackey/lackey-cms/42e75b5f33d92c1cb98dee1067045942ce64f7f3/modules/cms/client/img/blocks/select-arrow.png -------------------------------------------------------------------------------- /modules/cms/client/img/blocks/text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getlackey/lackey-cms/42e75b5f33d92c1cb98dee1067045942ce64f7f3/modules/cms/client/img/blocks/text.png -------------------------------------------------------------------------------- /modules/cms/client/img/svg/application.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/arrow-left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/arrow-right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/bin-filled.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/block/4-items-title.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/block/accordion.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/block/article-title.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/block/asset.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/block/contact.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/block/double-col-bullets.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/block/double-col.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/block/lock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/block/logos.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/block/media-copy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/block/newsletter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/block/person.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/block/section-header.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/block/title-background.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/block/title-copy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/block/title-cta.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/block/title-sub-copy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/block/title.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/blog-header.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Created with Sketch. 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Created with Sketch. 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/copy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Created with Sketch. 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/down-arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/envelope.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/eye-filled.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/eye.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 13 | 14 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/file.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Created with Sketch. 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/header.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Created with Sketch. 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/image.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Created with Sketch. 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/lock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/overflow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/pdf.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/plus.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 8 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/share.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/swirl.svg: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/tags.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 12 | 13 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/account.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/add-block.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/dashboard/analytics.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/dashboard/content.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/dashboard/homepage.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/dashboard/media.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/dashboard/tags.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/dashboard/users.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/editor/format-bold.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/editor/format-clear.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/editor/format-italic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/editor/format-list-bulleted.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/editor/format-list-numbered.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/editor/format-quote.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/editor/format-underline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/editor/insert-attachment.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/editor/insert-link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/settings/add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/settings/blocks.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/settings/changes.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/settings/dashboard.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/settings/settings.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/settings/tags.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/ui/settings/views.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/video.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /modules/cms/client/img/svg/view-thumb.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | 12 | -------------------------------------------------------------------------------- /modules/cms/client/js/growl.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, browser: true */ 2 | 'use strict'; 3 | /* 4 | Copyright 2016 Enigma Marketing Services Limited 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | 19 | module.exports = require('core/client/js/es5/growl'); 20 | -------------------------------------------------------------------------------- /modules/cms/client/js/header.js: -------------------------------------------------------------------------------- 1 | /* eslint no-cond-assign:0 */ 2 | /* jslint browser:true, node:true, esnext:true */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | const 20 | Manager = require('cms/client/js/manager/index.js'); 21 | 22 | Manager.init(); 23 | -------------------------------------------------------------------------------- /modules/cms/client/js/iframe.resolve.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true */ 2 | 'use strict'; 3 | module.exports = function (basePath, origPathName, givePrefix, addon) { 4 | var 5 | pathPrefix = basePath.replace(/.+?:\/\/.+?\/(.*)$/, '$1'), 6 | cleanPrefix = (pathPrefix && pathPrefix.length) ? (pathPrefix.replace(/([^\/]{1})\/$/, '$1')) : pathPrefix, 7 | pathName = origPathName.replace(/([^\/]{1})\/$/, '$1'), 8 | pathNameWithNoPrefix = (cleanPrefix && cleanPrefix.length) ? pathName.replace(new RegExp('^\/' + cleanPrefix), '') : pathName, 9 | adminPath = basePath.replace(/\/$/, '') + (addon || typeof addon === 'string' ? addon : '/admin') + pathNameWithNoPrefix; 10 | 11 | if (givePrefix) { 12 | return cleanPrefix; 13 | } 14 | 15 | return adminPath; 16 | }; 17 | -------------------------------------------------------------------------------- /modules/cms/client/js/language.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true */ 2 | 'use strict'; 3 | /* 4 | Copyright 2016 Enigma Marketing Services Limited 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | var table = require('core/client/js/table'); 19 | 20 | table.init(); 21 | -------------------------------------------------------------------------------- /modules/cms/client/js/manager/article.picker.ui.js: -------------------------------------------------------------------------------- 1 | /* eslint no-cond-assign:0, no-new:0 */ 2 | /* jslint browser:true, node:true, esnext:true */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | const Picker = require('cms/client/js/manager/picker.ui.js'); 20 | 21 | /** 22 | * @class 23 | */ 24 | class ArticlePickerUI extends Picker { 25 | 26 | get template() { 27 | 28 | return 'cms/cms/article-picker'; 29 | } 30 | 31 | get uri() { 32 | 33 | return '/cms/content?type=page' + this.options.taxonomies + '&q='; 34 | } 35 | 36 | selected(hook) { 37 | 38 | this.resolve(hook.getAttribute('data-lky-route')); 39 | } 40 | 41 | } 42 | 43 | module.exports = ArticlePickerUI; 44 | -------------------------------------------------------------------------------- /modules/cms/client/js/manager/block.picker.ui.js: -------------------------------------------------------------------------------- 1 | /* eslint no-cond-assign:0, no-new:0 */ 2 | /* jslint browser:true, node:true, esnext:true */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | const Picker = require('cms/client/js/manager/picker.ui.js'); 20 | 21 | /** 22 | * @class 23 | */ 24 | class BlockPickerUI extends Picker { 25 | 26 | get template() { 27 | 28 | return 'cms/cms/block-picker'; 29 | } 30 | 31 | get uri() { 32 | 33 | return '/cms/template?limit=100&type=block&q='; 34 | } 35 | 36 | selected(hook) { 37 | 38 | this.resolve(hook.getAttribute('data-lky-path')); 39 | } 40 | } 41 | 42 | module.exports = BlockPickerUI; 43 | -------------------------------------------------------------------------------- /modules/cms/client/js/manager/role.picker.ui.js: -------------------------------------------------------------------------------- 1 | /* eslint no-cond-assign:0, no-new:0 */ 2 | /* jslint browser:true, node:true, esnext:true */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | const Picker = require('cms/client/js/manager/picker.ui.js'); 20 | 21 | /** 22 | * @class 23 | */ 24 | class RolePickerUI extends Picker { 25 | 26 | get template() { 27 | 28 | return 'cms/cms/role-picker'; 29 | } 30 | 31 | get uri() { 32 | 33 | return '/cms/role?q='; 34 | } 35 | 36 | selected(hook) { 37 | this.resolve(hook.getAttribute('data-lky-data')); 38 | } 39 | 40 | } 41 | 42 | module.exports = RolePickerUI; 43 | -------------------------------------------------------------------------------- /modules/cms/client/js/page.js: -------------------------------------------------------------------------------- 1 | /* eslint no-cond-assign:0 */ 2 | /* jslint browser:true, node:true, esnext:true */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | require('cms/client/js/iframe'); 20 | require('cms/client/js/view'); 21 | -------------------------------------------------------------------------------- /modules/cms/client/js/pages.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true */ 2 | 'use strict'; 3 | /* 4 | Copyright 2016 Enigma Marketing Services Limited 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | var lackey = require('core/client/js'), 19 | api = require('core/client/js/api'); 20 | 21 | lackey.bind('lky:cms.page.new', 'submit', function (event, hook) { 22 | 23 | event.preventDefault(); 24 | event.stopPropagation(); 25 | 26 | api.create('/cms/content', lackey.form(hook)).then(function () { 27 | lackey.hide('#new'); 28 | //top.document.location.reload(true); 29 | }, function () { 30 | lackey.hide('#new'); 31 | //top.document.location.reload(true); 32 | }); 33 | 34 | return false; 35 | }); 36 | -------------------------------------------------------------------------------- /modules/cms/client/js/preview.js: -------------------------------------------------------------------------------- 1 | /* eslint no-cond-assign:0 */ 2 | /* jslint browser:true, node:true, esnext:true */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | require('cms/client/js/view'); 20 | -------------------------------------------------------------------------------- /modules/cms/client/js/table.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true */ 2 | 'use strict'; 3 | /* 4 | Copyright 2016 Enigma Marketing Services Limited 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | var table = require('core/client/js/table'), 19 | userDrop = require('cms/client/js/manager/user.dropdown.js'); 20 | 21 | table.init(); 22 | userDrop(); 23 | -------------------------------------------------------------------------------- /modules/cms/client/js/view.js: -------------------------------------------------------------------------------- 1 | /* eslint no-cond-assign:0 */ 2 | /* jslint browser:true, node:true, esnext:true */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | require('cms/client/js/wysiwyg').init(); 20 | require('cms/client/js/block-editor').init(); 21 | -------------------------------------------------------------------------------- /modules/cms/client/scss/_calendar.scss: -------------------------------------------------------------------------------- 1 | [data-lky-calendar] { 2 | border: 1px solid $color-lackey-light-blue; 3 | margin: auto; 4 | border-spacing: 0px; 5 | border-collapse: collapse; 6 | a { 7 | text-decoration: none; 8 | color: $color-lackey-dark-gray; 9 | &.active { 10 | background-color: $color-lackey-light-blue; 11 | color: white; 12 | } 13 | padding: 5px; 14 | border-radius: 20px; 15 | display: inline-block; 16 | } 17 | thead { 18 | background-color: $color-lackey-light-blue; 19 | color: white; 20 | a, 21 | a:hover, 22 | a:visited, 23 | a:link { 24 | color: white; 25 | } 26 | } 27 | td, 28 | th { 29 | padding: 5px; 30 | text-align: center; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /modules/cms/client/scss/_content-gallery.scss: -------------------------------------------------------------------------------- 1 | 2 | .templates { 3 | margin: 0px 150px 15px; 4 | text-align: center; 5 | border: 3px solid $color-lackey-light-blue; 6 | border-radius: 10px; 7 | .header{ 8 | background-color: $color-lackey-light-blue; 9 | padding: 25px; 10 | font-size: 18px; 11 | color: #fff; 12 | } 13 | 14 | section.templateContainer { 15 | display: flex; 16 | flex-wrap: wrap; 17 | align-items: center; 18 | flex-direction: row; 19 | justify-content: space-between; 20 | .template { 21 | max-width: 100%; 22 | cursor: pointer; 23 | box-sizing: border-box; 24 | display: flex; 25 | flex-direction: column; 26 | border: 1px solid white; 27 | figure { 28 | img { 29 | width:100%; 30 | } 31 | } 32 | 33 | p { 34 | flex: 1 0 auto; 35 | } 36 | 37 | &:hover { 38 | border: 1px solid $color-lackey-light-blue; 39 | } 40 | &.selected { 41 | background-color: $color-lackey-light-blue; 42 | border: 1px solid $color-lackey-light-blue; 43 | color: #fff; 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /modules/cms/client/scss/_fonts.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getlackey/lackey-cms/42e75b5f33d92c1cb98dee1067045942ce64f7f3/modules/cms/client/scss/_fonts.scss -------------------------------------------------------------------------------- /modules/cms/client/scss/_partials/_create-page.scss: -------------------------------------------------------------------------------- 1 | .create-page { 2 | h1 { 3 | font-size: 2rem; 4 | margin-bottom: 2rem; 5 | } 6 | 7 | label { 8 | color: #6c6c6c; 9 | align-self: center; 10 | 11 | &.choose { 12 | margin: 2rem 0 0 0; 13 | } 14 | } 15 | 16 | .name { 17 | display: flex; 18 | justify-content: flex-start; 19 | 20 | label { 21 | margin-right: 1rem; 22 | } 23 | 24 | input { 25 | flex: 1 1 auto; 26 | } 27 | } 28 | 29 | .table { 30 | th { 31 | padding: 0; 32 | margin-top: 0.5rem; 33 | } 34 | } 35 | 36 | button { 37 | appearance: none; 38 | background: $color-background-highlight; 39 | border: 0; 40 | outline: 0; 41 | color: #ffffff; 42 | padding: 0.2rem 0.5rem; 43 | margin: 0 0 0.5rem 0.5rem; 44 | cursor: pointer; 45 | font-size: 13px; 46 | padding: 6px 10px; 47 | text-decoration: none; 48 | cursor: default; 49 | 50 | &[type=submit] { 51 | margin-top: 2rem; 52 | } 53 | } 54 | } 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /modules/cms/client/scss/_partials/_overlay.scss: -------------------------------------------------------------------------------- 1 | .overlay { 2 | display:none; 3 | position: fixed; 4 | top: 0px; 5 | left: 0px; 6 | height: 100%; 7 | width: 100%; 8 | background-color: white; 9 | z-index: 999999; 10 | 11 | &.show { 12 | display: block; 13 | } 14 | } 15 | 16 | [data-lky-overlay] { 17 | background-color: rgba(0,0,0,0.5); 18 | z-index: 99999; 19 | position: fixed; 20 | width: 100%; 21 | height: 100%; 22 | top: 0px; 23 | left: 0px; 24 | } 25 | -------------------------------------------------------------------------------- /modules/cms/client/scss/_partials/_sidebar.scss: -------------------------------------------------------------------------------- 1 | .sidebar { 2 | position: fixed; 3 | width: 100%; 4 | height: 100%; 5 | background-color: rgba(1, 255, 201, 0.3); 6 | &:empty { 7 | display: none; 8 | } 9 | .column { 10 | width: 300px; 11 | float: left; 12 | margin: auto; 13 | margin-top: 50px; 14 | height: calc(100% - 50px); 15 | overflow-y: auto; 16 | background-color: #f5f5f5; 17 | color: #333; 18 | > ul { 19 | list-style: none; 20 | padding: 0px; 21 | margin: 0px; 22 | > li { 23 | > h5 { 24 | display: block; 25 | margin: 0px; 26 | padding: 10px; 27 | background-color: black; 28 | color: white; 29 | } 30 | > ul { 31 | list-style: none; 32 | padding: 0px; 33 | margin: 0px; 34 | > li { 35 | > label { 36 | display: flex; 37 | width: 100%; 38 | > input, 39 | > select, 40 | > span { 41 | flex: 1; 42 | } 43 | > span { 44 | padding: 3px; 45 | } 46 | } 47 | } 48 | } 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /modules/cms/client/scss/_partials/_structure/_main.scss: -------------------------------------------------------------------------------- 1 | [data-lky-component="structure"] { 2 | 3 | } 4 | 5 | [data-lky-component="structure-sections"] { 6 | h3 { 7 | color: $color-black; 8 | } 9 | ul { 10 | list-style: none; 11 | padding: 0px; 12 | margin: 0px; 13 | display: block; 14 | > li { 15 | clear: both; 16 | > img { 17 | float: left; 18 | padding-right: 10px; 19 | padding-bottom: 10px; 20 | } 21 | } 22 | } 23 | } 24 | 25 | [data-lky-component="Block"], [data-lky-component="block"] { 26 | color: $color-black; 27 | } 28 | 29 | .block-picker { 30 | height: 250px; 31 | overflow-y: auto; 32 | ul { 33 | list-style: none; 34 | margin: 0px; 35 | padding: 0px; 36 | li { 37 | label { 38 | input { 39 | margin-right: 20px; 40 | } 41 | img { 42 | margin-right: 20px; 43 | } 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /modules/cms/client/scss/_partials/_table-header.scss: -------------------------------------------------------------------------------- 1 | section.table-header { 2 | padding-top: 4rem; 3 | display: flex; 4 | flex-flow: wrap; 5 | flex-wrap: wrap; 6 | justify-content: space-between; 7 | 8 | .left, .right { 9 | display: flex; 10 | flex-flow: wrap; 11 | flex-wrap: wrap; 12 | align-items: center; 13 | } 14 | 15 | .left { 16 | justify-content: flex-start; 17 | align-items: center; 18 | } 19 | 20 | .right { 21 | justify-content: flex-end; 22 | align-items: center; 23 | } 24 | 25 | section.content-filter { 26 | flex: 1 1 100%; 27 | } 28 | 29 | .table-header { 30 | flex: 1 1 100%; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /modules/cms/client/scss/_partials/_tags.scss: -------------------------------------------------------------------------------- 1 | [data-tag] { 2 | display: block; 3 | background-color: $color-lackey-light-blue; 4 | color: white; 5 | padding: 10px 15px; 6 | margin-bottom: 3px; 7 | &[disabled] { 8 | background-color: $color-lackey-light-gray; 9 | color: #eee; 10 | } 11 | > a { 12 | float: right; 13 | cursor: pointer; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /modules/cms/client/scss/_partials/_treeview.scss: -------------------------------------------------------------------------------- 1 | .tree-view { 2 | ul { 3 | list-style: none; 4 | padding: 5px 10px; 5 | margin: 0px; 6 | } 7 | li { 8 | list-style: none; 9 | 10 | .fa { 11 | margin-right: 5px; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /modules/cms/client/scss/_partials/image-manager/_main.scss: -------------------------------------------------------------------------------- 1 | .image-manager { 2 | .sidebar { 3 | background: $color-light-gray; 4 | color: $color-dark-gray; 5 | float: left; 6 | height: inherit; 7 | width: 300px; 8 | padding: 5px 10px; 9 | [data-lky-hook="list"] { 10 | overflow-y: auto; 11 | height: 100%; 12 | } 13 | 14 | h5 { 15 | font-size: 1rem; 16 | margin: 5px 0px; 17 | } 18 | 19 | input { 20 | width: 100%; 21 | font-size: 1rem; 22 | } 23 | 24 | button { 25 | padding: 10px; 26 | margin: 5px; 27 | } 28 | 29 | [data-lky-hook="dropZone"] { 30 | border:2px solid $color-dark-gray; 31 | border-radius: 10px; 32 | padding: 10px; 33 | &:hover { 34 | background-color: lighten($color-light-gray,10%); 35 | } 36 | } 37 | 38 | } 39 | .miniatures { 40 | list-style: none; 41 | li { 42 | float: left; 43 | img, video { 44 | height: 100px; 45 | width: 100px; 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /modules/cms/client/scss/_switch.scss: -------------------------------------------------------------------------------- 1 | [data-lky-switch] { 2 | span { 3 | display: block; 4 | position: relative; 5 | cursor: pointer; 6 | outline: none; 7 | user-select: none; 8 | width: #{$switch-width * 2}; 9 | height: $switch-height; 10 | background-color: #dddddd; 11 | border-radius: $switch-width; 12 | } 13 | span:before, 14 | span:after { 15 | display: block; 16 | position: absolute; 17 | top: 1px; 18 | left: 1px; 19 | bottom: 1px; 20 | content: ""; 21 | } 22 | span:before { 23 | right: 1px; 24 | background-color: #f1f1f1; 25 | border-radius: $switch-width; 26 | transition: background 0.4s; 27 | } 28 | span:after { 29 | width: #{$switch-width - 2px}; 30 | background-color: #fff; 31 | border-radius: 100%; 32 | box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3); 33 | transition: margin 0.4s; 34 | } 35 | input { 36 | position: absolute; 37 | margin-left: -9999px; 38 | visibility: hidden; 39 | } 40 | input:checked + span:before { 41 | background-color: $color-background-highlight; 42 | } 43 | input:checked + span:after { 44 | margin-left: $switch-width; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /modules/cms/client/scss/_typography.scss: -------------------------------------------------------------------------------- 1 | h1, 2 | h2, 3 | h3 { 4 | font-family: 'Roboto', sans-serif; 5 | font-weight: bold; 6 | color: $color-lackey-light-blue; 7 | } 8 | 9 | h1 { 10 | font-size: $header-1-font-size; 11 | } 12 | 13 | h2 { 14 | font-size: $header-2-font-size; 15 | } 16 | 17 | h3 { 18 | font-size: $header-3-font-size; 19 | } 20 | -------------------------------------------------------------------------------- /modules/cms/client/scss/block-editor.scss: -------------------------------------------------------------------------------- 1 | @import "vars"; 2 | 3 | button.lky-edit-block { 4 | position: absolute; 5 | width: 1em; height: 1em; 6 | z-index: 100000; 7 | 8 | font-size: 3rem; 9 | background: { 10 | color: $color-background; 11 | image: url(../../../img/cms/cms/svg/ui/settings/settings.svg); 12 | size: 60%; 13 | position: center; 14 | repeat: no-repeat; 15 | } 16 | 17 | transition: background-color 0.5s $timing-material-decelerate; 18 | 19 | animation: target-change 0.5s $timing-material-standard 1; 20 | @keyframes target-change { 21 | from { background-color: $color-background-highlight; } 22 | to { background-color: $color-background; } 23 | } 24 | &[data-target-change] { animation: none; } 25 | 26 | &:hover { 27 | background-color: $color-background-accent; 28 | 29 | transition: background-color 0.2s $timing-material-standard; 30 | } 31 | } 32 | 33 | figure.lky-block-overlay { 34 | position: absolute; 35 | z-index: 99999; 36 | 37 | pointer-events: none; 38 | user-select: none; 39 | 40 | background-color: transparent; 41 | border: 2px dashed transparentize($color-background-highlight, 0.2); 42 | 43 | animation: target-change-overlay 0.7s $timing-material-sharp 1; 44 | @keyframes target-change-overlay { 45 | 0% { background-color: transparent; } 46 | 50% { background-color: transparentize($color-background-highlight, 0.8); } 47 | 100% { background-color: transparent; } 48 | } 49 | &[data-target-change] { animation: none; } 50 | } 51 | -------------------------------------------------------------------------------- /modules/cms/client/scss/media.scss: -------------------------------------------------------------------------------- 1 | @import "_vars"; 2 | 3 | 4 | [data-lky-component="media"], [data-lky-component="page-item"] { 5 | margin: 100px auto 0; 6 | 7 | > * { 8 | display: inline-block; 9 | vertical-align: middle; 10 | } 11 | 12 | > aside { 13 | margin-left: 50px; 14 | } 15 | 16 | section { 17 | 18 | } 19 | 20 | h3 { 21 | margin-top: 15px; 22 | } 23 | 24 | 25 | div.mediaContainer { 26 | width: 275px; 27 | 28 | img, video { 29 | width: 100%; 30 | } 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /modules/cms/client/scss/settings.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getlackey/lackey-cms/42e75b5f33d92c1cb98dee1067045942ce64f7f3/modules/cms/client/scss/settings.scss -------------------------------------------------------------------------------- /modules/cms/client/views/article-picker.dust: -------------------------------------------------------------------------------- 1 | {! Used by lackey-cms/modules/cms/client/js/manager/article.picker.js !} 2 | 9 | -------------------------------------------------------------------------------- /modules/cms/client/views/block-picker.dust: -------------------------------------------------------------------------------- 1 | {! Used by lackey-cms/modules/cms/client/js/manager/block.picker.js !} 2 | 9 | -------------------------------------------------------------------------------- /modules/cms/client/views/calendar.dust: -------------------------------------------------------------------------------- 1 | {! Used by lackey-cms/modules/cms/client/views/datetime-picker.dust !} 2 | 3 | 4 | 5 | 8 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | {#calendar} 27 | 28 | {#.} 29 | 34 | {/.} 35 | 36 | {/calendar} 37 | 38 |
6 | « 7 | 9 | {viewing|monthLongUTC} {viewing|yearUTC} 10 | 12 | » 13 |
MonTueWedThuFriSatSun
30 | 31 | {.} 32 | 33 |
39 | 40 | 48 | Time is relative to Coordinated Univestal Time UTC. 49 | 50 | 51 | -------------------------------------------------------------------------------- /modules/cms/client/views/datetime-picker.dust: -------------------------------------------------------------------------------- 1 | {! Used by lackey-cms/modules/cms/client/js/manager/datetime.picker.js !} 2 | 7 | -------------------------------------------------------------------------------- /modules/cms/client/views/role-picker.dust: -------------------------------------------------------------------------------- 1 | {! Used by lackey-cms/modules/cms/client/js/manager/article.picker.js !} 2 | 9 | -------------------------------------------------------------------------------- /modules/cms/client/views/source-editor.dust: -------------------------------------------------------------------------------- 1 | {! Used by lackey-cms/modules/cms/client/js/manager/article.picker.js !} 2 | 38 | -------------------------------------------------------------------------------- /modules/cms/client/views/sources.dust: -------------------------------------------------------------------------------- 1 | {! Used by lackey-cms/modules/cms/client/views/gallery.dust !} 2 | 3 | 4 | {media.source} 5 | 6 | 7 | {media.mime} 8 | 9 | 10 | default 11 | 12 | 13 | 14 | 15 | 16 | {#media.alternatives} 17 | 18 | 19 | {src} 20 | 21 | 22 | {mime} 23 | 24 | 25 | {media} 26 | 27 | 28 | 29 | 30 | 31 | 32 | {/media.alternatives} 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /modules/cms/client/views/structure/articles.dust: -------------------------------------------------------------------------------- 1 | {! Used by lackey-cms/modules/cms/client/views/article-picker.dust !} 2 | {#data} 3 |
  • 4 |
    5 | {name} 6 |
    {route}
    7 |
    8 |
    9 | 10 |
    11 |
  • 12 | {/data} 13 | -------------------------------------------------------------------------------- /modules/cms/client/views/structure/blocks.dust: -------------------------------------------------------------------------------- 1 | {! Used by lackey-cms/modules/cms/client/views/block-picker.dust !} 2 | {#data} 3 |
  • 4 | 5 |
    6 | 7 |
    8 | 9 |
  • 10 | {/data} 11 | -------------------------------------------------------------------------------- /modules/cms/client/views/structure/item.dust: -------------------------------------------------------------------------------- 1 | {! Used by lackey-cms/modules/cms/client/views/structure/sections.dust !} 2 |
    8 | 9 | {?label}{:else}{/label} 10 | 11 |
    12 | 13 | 14 |
    15 | 16 | 17 |
    18 |
    19 | 20 | {?index}{/index} 21 |
    22 | -------------------------------------------------------------------------------- /modules/cms/client/views/structure/sections.dust: -------------------------------------------------------------------------------- 1 | {! Used by lackey-cms/modules/cms/client/views/settings.dust !} 2 | {#expose}{@path root=context path=path exposeType=type itemPath=path allowEmpty=1} 3 | {@switch key=exposeType} 4 | 5 | {:List} 6 |
    7 | 8 | 9 | {#items} 10 | {@templateData template=template} 11 | {>"cms/cms/structure/item" thumb=thumb index=$idx label=""/} 12 | {/templateData} 13 | {/items} 14 |
    15 | 16 | {:Block} 17 | {@templateData template=template} 18 | {>"cms/cms/structure/item" thumb=thumb locked="1"/} 19 | {/templateData} 20 | 21 | {/switch} 22 | {/path}{/expose} 23 | -------------------------------------------------------------------------------- /modules/cms/client/views/structure/taxonomies.dust: -------------------------------------------------------------------------------- 1 |
    2 | {#template.allowTaxonomies} 3 | 4 | {description} 5 | 6 | 18 | 19 | 20 | {:else} 21 |

    Tagging isn't enabled for this element!

    22 | {/template.allowTaxonomies} 23 |
    24 | 25 | {?template.taxonomies} 26 |
    27 | 28 | 29 | 37 |
    38 | {/template.taxonomies} 39 | -------------------------------------------------------------------------------- /modules/cms/client/views/structure/taxonomy.dust: -------------------------------------------------------------------------------- 1 | {! Used by lackey-cms/modules/cms/client/views/article-picker.dust !} 2 | {#data} 3 |
  • 4 |
    5 | {?label}{label}{:else}{name}{/label} 6 |
    {count}
    7 |
    8 |
    9 | 10 |
    11 |
  • 12 | {/data} 13 | -------------------------------------------------------------------------------- /modules/cms/client/views/structure/users.dust: -------------------------------------------------------------------------------- 1 | {! Used by lackey-cms/modules/cms/client/views/user-picker.dust !} 2 | {#data} 3 | 4 | 5 | 6 | 7 | {name} 8 | {email} 9 | 10 | 11 | 12 | 13 | {/data} 14 | 42 | 43 | -------------------------------------------------------------------------------- /modules/cms/client/views/taxonomy-picker.dust: -------------------------------------------------------------------------------- 1 | {! Used by lackey-cms/modules/cms/client/js/manager/article.picker.js !} 2 | 11 | -------------------------------------------------------------------------------- /modules/cms/client/views/user-picker.dust: -------------------------------------------------------------------------------- 1 | {! Used by lackey-cms/modules/cms/client/js/manager/user.picker.js !} 2 | 9 | -------------------------------------------------------------------------------- /modules/cms/server/controllers/preview.js: -------------------------------------------------------------------------------- 1 | /* jslint esnext:true, node:true */ 2 | /* globals LACKEY_PATH */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | const 21 | SUtils = require(LACKEY_PATH).utils, 22 | CRUD = SUtils.cmsMod('core').controller('crud.injection', true); 23 | 24 | /** 25 | * @class 26 | * @name UserController 27 | * Users CMS Controller 28 | * 29 | */ 30 | class PreviewController extends CRUD { 31 | 32 | /** 33 | * @override 34 | * @see lackey-cms/modules/core/server/controllers/CrudInjectionController#field 35 | */ 36 | static get field() { 37 | return this._overriden('field', 'previews'); 38 | } 39 | 40 | static getByContentId(Model, req, res) { 41 | let contentId = req.params.contentId; 42 | Model.findOneBy('contentId', contentId) 43 | .then((preview) => { 44 | res.api(preview); 45 | }); 46 | } 47 | 48 | } 49 | 50 | module.exports = PreviewController; 51 | -------------------------------------------------------------------------------- /modules/cms/server/controllers/role.js: -------------------------------------------------------------------------------- 1 | /* jslint esnext:true, node:true */ 2 | /* globals LACKEY_PATH */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | const SUtils = require(LACKEY_PATH).utils; 21 | 22 | module.exports = SUtils 23 | .waitForAs('lackey-cms/modules/cms/server/controllers/role', 24 | SUtils.cmsMod('core').model('role'), 25 | SUtils.cmsMod('core').controller('crud') 26 | ) 27 | .then((Model, Crud) => { 28 | class Controller extends Crud { 29 | 30 | static get model() { 31 | return this._overriden('model', Model); 32 | } 33 | 34 | static get field() { 35 | return this._overriden('field', 'role'); 36 | } 37 | 38 | } 39 | 40 | return Promise.resolve(Controller); 41 | }); 42 | -------------------------------------------------------------------------------- /modules/cms/server/controllers/template.js: -------------------------------------------------------------------------------- 1 | /* jslint esnext:true, node:true */ 2 | 'use strict'; 3 | /* 4 | Copyright 2016 Enigma Marketing Services Limited 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | 19 | const SUtils = require(LACKEY_PATH).utils; 20 | 21 | module.exports = SUtils 22 | .waitForAs('templateCtrl', 23 | SUtils.cmsMod('core').model('template'), 24 | SUtils.cmsMod('core').controller('crud') 25 | ) 26 | .then((Model, Crud) => { 27 | class Controller extends Crud { 28 | 29 | static get model() { 30 | return this._overriden('model', Model); 31 | } 32 | 33 | static get field() { 34 | return this._overriden('field', 'template'); 35 | } 36 | 37 | } 38 | 39 | return Promise.resolve(Controller); 40 | }); 41 | -------------------------------------------------------------------------------- /modules/cms/server/controllers/translation.js: -------------------------------------------------------------------------------- 1 | /* jslint esnext:true, node:true */ 2 | 'use strict'; 3 | /* 4 | Copyright 2016 Enigma Marketing Services Limited 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | 19 | 20 | const SUtils = require(LACKEY_PATH).utils; 21 | 22 | module.exports = SUtils 23 | .waitForAs('lackey-cms/modules/cms/server/controllers/translation', 24 | SUtils.cmsMod('core').model('translation'), 25 | SUtils.cmsMod('core').controller('crud') 26 | ) 27 | .then((Model, Crud) => { 28 | class Controller extends Crud { 29 | 30 | static get model() { 31 | return this._overriden('model', Model); 32 | } 33 | 34 | static get field() { 35 | return this._overriden('field', 'translationModel'); 36 | } 37 | 38 | } 39 | 40 | return Promise.resolve(Controller); 41 | }); 42 | -------------------------------------------------------------------------------- /modules/cms/server/lib/dust/acl.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | /* eslint no-param-reassign:0 */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | const SUtils = require(LACKEY_PATH).utils; 21 | 22 | module.exports = (dust) => { 23 | 24 | dust.helpers.acl = function (chunk, context, bodies, params) { 25 | let user = context.get('admin'), 26 | perm = params.perm, 27 | method = params.method; 28 | 29 | return SUtils.cmsMod('core').model('user') 30 | .then((User) => { 31 | return User.findById(user.id); 32 | }).then((userModel) => { 33 | return userModel.isAllowed(perm, method); 34 | }) 35 | .then((isAllowed) => { 36 | if (isAllowed) { 37 | return chunk; 38 | } 39 | return false; 40 | }, (error) => { 41 | /* istanbul ignore next */ 42 | console.error(error); 43 | }); 44 | }; 45 | }; 46 | -------------------------------------------------------------------------------- /modules/cms/server/lib/dust/acronym.js: -------------------------------------------------------------------------------- 1 | /*jslint node: true */ 2 | 'use strict'; 3 | 4 | /** 5 | * @param {DustEngine} dust 6 | */ 7 | module.exports = (dust) => { 8 | dust.filters.acronym = function (value) { 9 | return value.match(/\b([A-Za-z])/g).join('').toUpperCase(); 10 | }; 11 | }; 12 | -------------------------------------------------------------------------------- /modules/cms/server/lib/dust/attr.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | 'use strict'; 3 | /* 4 | Copyright 2016 Enigma Marketing Services Limited 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | 19 | const 20 | editable = require('./editable'), 21 | escape = require('escape-html'); 22 | 23 | 24 | module.exports = (dust) => { 25 | 26 | dust.helpers.attr = function (chunk, context, bodies, params) { 27 | let 28 | content = params.content, 29 | field = params.field || false, 30 | layout = content.layout, 31 | variant = params.variant, 32 | type = params.type || 'doc'; 33 | 34 | try { 35 | if (layout && layout.type) { 36 | chunk.write(escape(editable.fromLayout(layout, params.path, field, variant, type, params.path, 'text').replace(/\n/g, ' '))); 37 | } 38 | } catch (error) { 39 | throw error; 40 | } 41 | 42 | return chunk; 43 | }; 44 | 45 | }; 46 | -------------------------------------------------------------------------------- /modules/cms/server/lib/dust/cms.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getlackey/lackey-cms/42e75b5f33d92c1cb98dee1067045942ce64f7f3/modules/cms/server/lib/dust/cms.js -------------------------------------------------------------------------------- /modules/cms/server/lib/dust/config.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | /* eslint no-param-reassign:0 */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | const configuration = require(LACKEY_PATH).configuration; 21 | 22 | module.exports = (dust) => { 23 | 24 | dust.helpers.config = function (chunk, context, bodies) { 25 | 26 | if (bodies.block) { 27 | return chunk.map((innerChunk) => { 28 | configuration() 29 | .then((config) => { 30 | innerChunk = innerChunk.render(bodies.block, context.push(config._map)); 31 | innerChunk.end(); 32 | }); 33 | }); 34 | } 35 | return chunk; 36 | }; 37 | 38 | }; 39 | -------------------------------------------------------------------------------- /modules/cms/server/lib/dust/error.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | 'use strict'; 3 | /* 4 | Copyright 2016 Enigma Marketing Services Limited 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | module.exports = (dust) => { 19 | 20 | dust.helpers.error = function (chunk, context, bodies, params) { 21 | try { 22 | if ((context.get && context.get('edit')) || context.edit) { 23 | chunk.write('
    '); 24 | chunk.write('

    ' + (params ? params.name : 'Error') + '

    '); 25 | chunk.write('
    ');
    26 |                 chunk.write(((params && params.stack) ? params.stack : '') + '\n' + JSON.stringify(context, null, 4));
    27 |                 chunk.write('
    '); 28 | chunk.write('
    '); 29 | } else { 30 | chunk.end(); 31 | } 32 | } catch(e) { 33 | console.error(e); 34 | } 35 | }; 36 | 37 | }; 38 | -------------------------------------------------------------------------------- /modules/cms/server/lib/dust/filter.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | /* globals LACKEY_PATH */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | const SCli = require(LACKEY_PATH).cli; 21 | 22 | module.exports = (dust) => { 23 | 24 | dust.helpers.filter = function (chunk, context, bodies, params) { 25 | SCli.debug('lackey-cms/modules/cms/server/lib/dust/filter'); 26 | 27 | let list = params.list, 28 | key = params.key, 29 | value = params.value, 30 | idx = 0, 31 | output = chunk; 32 | 33 | list.forEach(item => { 34 | if (item[key] === value) { 35 | item.$idx = idx++; 36 | output = output.render(bodies.block, context.push(item)); 37 | } 38 | }); 39 | 40 | return output; 41 | 42 | }; 43 | 44 | }; 45 | -------------------------------------------------------------------------------- /modules/cms/server/lib/dust/qs.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | /* eslint no-param-reassign:0 */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | module.exports = (dust) => { 21 | 22 | dust.helpers.qs = function (chunk, context, bodies, params) { 23 | let except = (params.except) ? params.except.split(',') : [], 24 | method = params.method || 'GET', 25 | query = (method === 'POST') ? context.get('post') : context.get('req.query'), 26 | final = ''; 27 | 28 | Object.keys(query).forEach((key) => { 29 | if (except.indexOf(key) < 0) { 30 | final = (final === '') ? final + '?' + key + '=' + encodeURIComponent(query[key]) : final + '&' + key + '=' + encodeURIComponent(query[key]); 31 | } 32 | }); 33 | 34 | return final; 35 | }; 36 | }; 37 | -------------------------------------------------------------------------------- /modules/cms/server/lib/dust/sort.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | 'use strict'; 3 | /* 4 | Copyright 2016 Enigma Marketing Services Limited 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | 19 | module.exports = (dust) => { 20 | dust.helpers.sort = function (chunk, context, bodies, params) { 21 | params.items.sort(function (a, b) { 22 | if (params.by) { 23 | return ((a[params.by] < b[params.by]) ? -1 : ((a[params.by] > b[params.by]) ? 1 : 0)); 24 | } else { 25 | return ((a < b) ? -1 : ((a > b) ? 1 : 0)); 26 | } 27 | }); 28 | params.items.forEach(function (item) { 29 | chunk.render(bodies.block, context.push(item)); 30 | }); 31 | return chunk; 32 | }; 33 | }; 34 | -------------------------------------------------------------------------------- /modules/cms/server/lib/dust/user-has.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | /* eslint no-param-reassign:0 */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | module.exports = (dust) => { 21 | 22 | dust.helpers.userHas = function (chunk, context, bodies, params) { 23 | let 24 | kind = params.type || 'roles', 25 | user = params.user, 26 | blocks = Object.keys(bodies), 27 | found = false; 28 | 29 | if (!user) { 30 | return chunk; 31 | } 32 | 33 | blocks.forEach((blockName) => { 34 | 35 | if (found) { 36 | return; 37 | } 38 | 39 | user[kind].forEach((item) => { 40 | if (item.name === blockName) { 41 | found = true; 42 | chunk = chunk.render(bodies[blockName], context.push(item)); 43 | } 44 | }); 45 | }); 46 | 47 | if (!found) { 48 | chunk = chunk.render(bodies.block, context); 49 | } 50 | 51 | return chunk; 52 | }; 53 | 54 | }; 55 | -------------------------------------------------------------------------------- /modules/cms/server/views/activity-stream.dust: -------------------------------------------------------------------------------- 1 | {>"cms/cms/main"/} 2 | 3 | { 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | {#data.list} 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | {/list} 35 | 36 |
    Date / TimeUserMethodPathResponseActions
    22 |
    {createdAt}{author.name}{method}{url}{response.status}
    37 | 38 | {/body} 39 | -------------------------------------------------------------------------------- /modules/cms/server/views/contentedit.dust: -------------------------------------------------------------------------------- 1 | {>"cms/cms/main"/} 2 | 3 | { 5 |

    Content Edit

    6 |
    7 | {#data.content} 8 | 9 | 10 | 11 | 12 | 13 | 20 | 21 | 28 | 29 | 30 | {/data.content} 31 |
    32 | 33 | {/body} 34 | -------------------------------------------------------------------------------- /modules/cms/server/views/dashboard.dust: -------------------------------------------------------------------------------- 1 | {>"cms/cms/main"/} 2 | 3 | {"cms/core/main"/} 4 | 5 | { 7 | 8 | .facebook-embed { 9 | background-color: white; 10 | width: 474px; 11 | box-shadow: 0 0 0 1.5px rgba(0, 0, 0, .1) inset, 0 1px 1px rgba(0, 0, 0, .05); 12 | margin: auto; 13 | margin-top: 50px; 14 | 15 | font-family: helvetica, arial, sans-serif; 16 | color: rgb(59,89,152); 17 | } 18 | .facebook-embed h2 { 19 | font-weight: 500; 20 | font-size: 18px; 21 | line-height: 22px; 22 | margin-bottom: 5px; 23 | } 24 | .facebook-embed .facebook-image div { 25 | height: 246px; 26 | } 27 | 28 | 29 | 30 | 31 | 40 | 41 | 42 | 43 | 44 | {/body} 45 | 46 | -------------------------------------------------------------------------------- /modules/cms/server/views/media-create.dust: -------------------------------------------------------------------------------- 1 | {>"cms/cms/main"/} 2 | 3 | { 5 |

    Add Media

    6 | 7 |

    Add local file

    8 |
    9 | 10 |
    11 |
    12 |
    13 | Drop file here 14 | 15 |
    16 |
    17 | 18 |
    19 |
    20 | 21 |
    22 |
    23 |
    24 |
    25 |

    Add external asset

    26 |
    27 | 28 |
    29 | 30 | {/body} 31 | -------------------------------------------------------------------------------- /modules/cms/server/views/page.dust: -------------------------------------------------------------------------------- 1 | {>"cms/core/main"/} 2 | 3 | { 6 | {/body} 7 | -------------------------------------------------------------------------------- /modules/cms/server/views/partials/user.dust: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | {?admin.image.source} 4 | 5 | {:else} 6 | 7 | {/admin.image.source} 8 |
    9 | {admin.name} 10 | 16 |
    17 | -------------------------------------------------------------------------------- /modules/cms/server/views/redirect-create.dust: -------------------------------------------------------------------------------- 1 | {>"cms/cms/main"/} 2 | 3 | { 5 |

    Create Redirect

    6 |
    7 | 11 | 15 | 22 | 23 |
    24 | 25 | {/body} 26 | -------------------------------------------------------------------------------- /modules/cms/server/views/templates/blog.dust: -------------------------------------------------------------------------------- 1 | {>"cms/core/main"/} 2 | 3 | { 5 | {@image content=data.content editMode=edit path="image" path=path default="img/cms/cms/Star-Wars-Trilogy-Poster-2.jpg"/} 6 |
    7 | 19 |

    20 | {@editable content=data.content editMode=edit path="title" type="inline" route=path}{/editable} 21 |

    22 |
    23 |
    24 | {@editable content=data.content editMode=edit path="excert" route=path}{/editable} 25 |
    26 |
    27 | {@editable content=data.content editMode=edit path="body" route=path}{/editable} 28 |
    29 | 30 |
    
    31 | {/body}
    32 | 
    
    
    --------------------------------------------------------------------------------
    /modules/cms/server/views/user-create.dust:
    --------------------------------------------------------------------------------
     1 | {>"cms/cms/main"/}
     2 | 
     3 | {
     5 |     

    New User

    6 |
    7 | 8 | 12 | 16 | 24 | 27 |
    28 | 29 | {/body} 30 | -------------------------------------------------------------------------------- /modules/cms/server/views/user-set-password.dust: -------------------------------------------------------------------------------- 1 | {>"cms/core/main"/} 2 | 3 | { 5 |
    6 |

    Account Details

    7 |
    8 |
    9 |
    10 |
    11 | 15 | 16 | 21 | 24 |
    25 | 26 |
    27 | 28 | 29 | {/body} 30 | -------------------------------------------------------------------------------- /modules/cms/server/views/variant.dust: -------------------------------------------------------------------------------- 1 | {>"cms/core/main"/} 2 | 3 | {"cms/core/modal"/} 2 | 3 | { 5 |

    Create Page

    6 |
    7 |
    8 | 9 | 10 |
    11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | {#data.templates} 24 | 25 | 26 | 29 | 32 | 35 | 38 | 39 | 40 | {/data.templates} 41 | 42 |
    PreviewTemplatePrefix
    27 | 28 | 30 | {name} 31 | 33 |
    {prefix}
    34 |
    36 | 37 |
    43 | 44 |
    45 | 46 | {/body} 47 | -------------------------------------------------------------------------------- /modules/core/client/views/create-user-modal.dust: -------------------------------------------------------------------------------- 1 | {>"cms/core/modal"/} 2 | 3 | { 5 |

    New User

    6 |
    7 | 8 | 12 | 16 | 24 | 27 |
    28 | 29 | {/body} 30 | -------------------------------------------------------------------------------- /modules/core/client/views/fullscreen.dust: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | {+body/} 4 |
    5 |
    6 | -------------------------------------------------------------------------------- /modules/core/client/views/modal.dust: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | 11 |
    12 | -------------------------------------------------------------------------------- /modules/core/client/views/taxonomy-modal.dust: -------------------------------------------------------------------------------- 1 | {>"cms/core/modal"/} 2 | 3 | { 5 |
    6 |

    Tag Info

    7 |
    8 |
    9 |
    10 |

    Name

    11 | {data.taxonomy.name} 12 | 13 |

    Label

    14 | {data.taxonomy.label} 15 | 16 |

    Type

    17 | {data.taxonomy.type.name} 18 | 19 |

    Created At

    20 | {data.taxonomy.createdAt} 21 |
    22 |
    23 |
    24 |
    25 |
    {data.media|media|s}
    26 |
    27 |
    28 | 29 | {/body} 30 | -------------------------------------------------------------------------------- /modules/core/index.js: -------------------------------------------------------------------------------- 1 | /* eslint no-underscore-dangle:0 */ 2 | /* jslint esnext:true, node:true */ 3 | /* globals LACKEY_PATH */ 4 | 'use strict'; 5 | 6 | const SUtils = require(LACKEY_PATH).utils; 7 | 8 | module.exports = (instance) => { 9 | return SUtils 10 | .waitForAs( 11 | 'lackey-cms/modules/core', 12 | require('./server/controllers/errors'), 13 | require('./server/controllers/activitylog') 14 | ) 15 | .then((errors, activityLog) => { 16 | instance.addPostware(errors.on404); 17 | instance.addMiddleware(activityLog.capture); 18 | instance.addDustHelper(require('./shared/dust/iterate')); 19 | instance.addDustHelper(require('./shared/dust/path')); 20 | instance.addDustHelper(require('./shared/dust/hashmap')); 21 | instance.addDustHelper(require('./shared/dust/list')); 22 | instance.addDustHelper(require('./shared/dust/switch')); 23 | instance.addDustHelper(require('./shared/dust/youtube')); 24 | instance.addDustHelper(require('./shared/dust/try')); 25 | instance.addDustHelper(require('./shared/dust/pretty')); 26 | }); 27 | }; 28 | -------------------------------------------------------------------------------- /modules/core/server/controllers/errors.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | 'use strict'; 3 | /* 4 | Copyright 2016 Enigma Marketing Services Limited 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | 19 | module.exports = Promise.resolve({ 20 | on404: (req, res) => { 21 | res.status(404); 22 | res.print(['~/core/404', 'cms/core/404'], { 23 | path: req.path 24 | }); 25 | 26 | }, 27 | on403: (req, res) => { 28 | 29 | res.status(403); 30 | res.print(['~/core/403', 'cms/core/403'], { 31 | path: req.path 32 | }); 33 | 34 | }, 35 | on500: (req, res) => { 36 | 37 | res.status(500); 38 | res.print(['~/core/500', 'cms/core/500'], { 39 | path: req.path 40 | }); 41 | 42 | } 43 | }); 44 | -------------------------------------------------------------------------------- /modules/core/server/models/media/bucket.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getlackey/lackey-cms/42e75b5f33d92c1cb98dee1067045942ce64f7f3/modules/core/server/models/media/bucket.js -------------------------------------------------------------------------------- /modules/core/server/routes/sitemap.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | 'use strict'; 3 | /* 4 | Copyright 2016 Enigma Marketing Services Limited 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | 19 | 20 | 21 | const sitemap = require(LACKEY_PATH).sitemap; 22 | 23 | module.exports = (server, config) => { 24 | server.get('/sitemap.xml', function (req, res) { 25 | res.header('Content-Type', 'application/xml'); 26 | res.print('cms/core/sitemap', { 27 | urls: sitemap.getCached(), 28 | host: config.get('host') 29 | }); 30 | 31 | }); 32 | 33 | return Promise.resolve(); 34 | }; 35 | -------------------------------------------------------------------------------- /modules/core/server/views/404.dust: -------------------------------------------------------------------------------- 1 | {>"cms/core/main"/} 2 | 9 | -------------------------------------------------------------------------------- /modules/core/server/views/article.dust: -------------------------------------------------------------------------------- 1 | {>"cms/core/main"/} 2 | 3 | {Blimey! 5 | 6 | Path `{path}` doesn't exist 7 | {/body} 8 | -------------------------------------------------------------------------------- /modules/core/server/views/error.dust: -------------------------------------------------------------------------------- 1 | {>"cms/core/main"/} 2 | 3 | 15 | -------------------------------------------------------------------------------- /modules/core/server/views/main.dust: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {! to migrate elseewhre !} 5 | 6 | 7 | 8 | {#stylesheets} 9 | 10 | {/stylesheets} 11 | 12 | 13 | {+body /} 14 | {#javascripts} 15 | 16 | {/javascripts} 17 | 18 | 19 | -------------------------------------------------------------------------------- /modules/core/server/views/partials/header.dust: -------------------------------------------------------------------------------- 1 |
    2 |

    Lackey

    3 |
    4 | -------------------------------------------------------------------------------- /modules/core/server/views/sitemap.dust: -------------------------------------------------------------------------------- 1 | 2 | 3 | {#data.urls} 4 | 5 | {url|base} 6 | {lastmod} 7 | {changefreq} 8 | {priority} 9 | 10 | {/data.urls} 11 | 12 | -------------------------------------------------------------------------------- /modules/core/server/views/yaml.dust: -------------------------------------------------------------------------------- 1 | {data.yaml|s} 2 | -------------------------------------------------------------------------------- /modules/core/shared/dust/hashmap.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true, -W053: true */ 2 | 'use strict'; 3 | /* 4 | Copyright 2016 Enigma Marketing Services Limited 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | 19 | module.exports = (dust) => { 20 | 21 | dust.helpers.hashmap = function (chunk, context, bodies, params) { 22 | 23 | let map = params.map || {}, 24 | as = params.iterator || '$key'; 25 | Object.keys(map).forEach(function (key) { 26 | if (map[key]) { 27 | if (typeof map[key] === 'string') { 28 | map[key] = new String(map[key]); // eslint-disable-line no-new-wrappers 29 | } else if (typeof map[key] === 'number') { 30 | map[key] = new Number(map[key]); // eslint-disable-line no-new-wrappers 31 | } 32 | map[key][as] = key; 33 | chunk.render(bodies.block, context.push(map[key])); 34 | } 35 | }); 36 | 37 | return chunk; 38 | 39 | }; 40 | 41 | }; 42 | -------------------------------------------------------------------------------- /modules/core/shared/dust/is.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | /* eslint no-param-reassign:0 */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | module.exports = (dust) => { 21 | 22 | dust.helpers.is = function (chunk, context, bodies, params) { 23 | 24 | let type = params.type, 25 | key = params.key, 26 | equals = typeof key === type; 27 | 28 | if (type === 'array') { 29 | equals = Array.isArray(key); 30 | } 31 | 32 | let template = equals ? bodies.block : bodies.else; 33 | 34 | if (template) { 35 | chunk = chunk.render(template, context); 36 | } 37 | return chunk; 38 | 39 | 40 | }; 41 | }; 42 | -------------------------------------------------------------------------------- /modules/core/shared/dust/iterate.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | /* eslint no-param-reassign:0 */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | module.exports = (dust) => { 21 | 22 | dust.helpers.iterate = function (chunk, context, bodies, params) { 23 | 24 | let from = params.from || 0, 25 | to = params.to || 0, 26 | as = params.iterator || '$idx'; 27 | 28 | if (from <= to) { 29 | for (var i = from; i <= to; i++) { 30 | let data = {}; 31 | data[as] = +i; 32 | chunk = chunk.render(bodies.block, context.push(data)); 33 | } 34 | } 35 | 36 | return chunk; 37 | 38 | }; 39 | 40 | dust.helpers.iter = function (chunk, context, bodies, params) { 41 | var obj = params.context; 42 | Object.keys(obj).forEach(function (key) { 43 | chunk.render(bodies.block, context.push({key: key, value: obj[key]})); 44 | }); 45 | }; 46 | 47 | }; 48 | -------------------------------------------------------------------------------- /modules/core/shared/dust/list.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | 'use strict'; 3 | /* 4 | Copyright 2016 Enigma Marketing Services Limited 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | 19 | module.exports = (dust) => { 20 | 21 | dust.helpers.list = function (chunk, context, bodies, params) { 22 | 23 | let list = params.list || [], 24 | as = params.iterator || '$key'; 25 | 26 | list.forEach(function (item, index) { 27 | item[as] = index; 28 | chunk.render(bodies.block, context.push(item)); 29 | }); 30 | 31 | return chunk; 32 | 33 | }; 34 | 35 | }; 36 | -------------------------------------------------------------------------------- /modules/core/shared/dust/log.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | /* eslint no-param-reassign:0 */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | module.exports = (dust) => { 21 | 22 | // screw TypeError: Converting circular structure to JSON 23 | dust.helpers.log = function (chunk, context, bodies, params) { 24 | console.log('DUST LOG', params.key); 25 | chunk.end(); 26 | }; 27 | }; 28 | -------------------------------------------------------------------------------- /modules/core/shared/dust/pretty.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | /* eslint no-param-reassign:0, curly:0, eqeqeq:0 */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | function censor(censorObj) { 21 | var i = 0; 22 | 23 | return function (key, value) { 24 | if (i !== 0 && typeof (censorObj) === 'object' && typeof (value) == 'object' && censorObj == value) 25 | return '[Circular]'; 26 | 27 | if (i >= 29) // seems to be a harded maximum of 30 serialized objects? 28 | return '[Unknown]'; 29 | 30 | ++i; // so we know we aren't using the original object anymore 31 | 32 | return value; 33 | }; 34 | } 35 | 36 | module.exports = (dust) => { 37 | 38 | dust.filters.pretty = function (value) { 39 | try { 40 | return JSON.stringify(value, censor(value), 4); 41 | } catch (e) { 42 | console.log(value); 43 | return e.toString(); 44 | } 45 | }; 46 | }; 47 | -------------------------------------------------------------------------------- /modules/core/shared/dust/split.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | /* globals LACKEY_PATH */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | module.exports = (dust) => { 21 | dust.helpers.split = function (chunk, context, bodies, params) { 22 | let key = params.key, 23 | delim = params.delim; 24 | return chunk.render(bodies.block, context.push({split: key.split(delim)})); 25 | }; 26 | }; 27 | -------------------------------------------------------------------------------- /modules/core/shared/dust/switch.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | /* eslint no-param-reassign:0 */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | module.exports = (dust) => { 21 | 22 | dust.helpers.switch = function (chunk, context, bodies, params) { 23 | 24 | let value = params.key, 25 | keys = Object.keys(bodies), 26 | template = bodies.block; 27 | 28 | if(keys.indexOf(value) !== -1) { 29 | template = bodies[value]; 30 | } 31 | 32 | if (template) { 33 | chunk = chunk.render(template, context); 34 | } 35 | return chunk; 36 | 37 | 38 | }; 39 | }; 40 | -------------------------------------------------------------------------------- /modules/core/shared/dust/try.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | /* eslint no-param-reassign:0 */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | module.exports = (dust) => { 21 | 22 | dust.helpers.try = function (chunk, context, bodies) { 23 | 24 | try { 25 | chunk.render(bodies.block, context); 26 | } catch(exception) { 27 | chunk.render(bodies.catch, context); 28 | } 29 | return chunk; 30 | 31 | 32 | }; 33 | }; 34 | -------------------------------------------------------------------------------- /modules/core/shared/views/media-filter.dust: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 |
    5 | 6 | 9 |
    10 | 11 |
    12 |
    13 |
    14 | 15 |
    16 |
    17 | 18 | 19 | 20 | 21 | 22 |
    23 |
    24 |
    25 | -------------------------------------------------------------------------------- /modules/core/shared/views/table-value.dust: -------------------------------------------------------------------------------- 1 | {?value.href} 2 | {value.label} 3 | {:else} 4 | {?value.date} 5 | {@formatDate val=value.date weekday="short"/} {@formatDate val=value.date day="numeric"/} {@formatDate val=value.date month="short"/} {@formatDate val=value.date hour="numeric" minute="numeric"/} 6 | {:else} 7 | {value} 8 | {/value.date} 9 | {/value.href} 10 | -------------------------------------------------------------------------------- /modules/core/shared/views/tag-filter.dust: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 |
    5 | 6 | 9 |
    10 | 11 |
    12 |
    13 |
    14 | 15 |
    16 |
    17 |
    18 | -------------------------------------------------------------------------------- /modules/core/shared/views/user-filter.dust: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 |
    5 | 6 | 9 |
    10 | 11 |
    12 |
    13 |
    14 | 15 |
    16 |
    17 | 18 | 19 | 20 | 21 | 22 |
    23 |
    24 |
    25 | -------------------------------------------------------------------------------- /modules/core/test/server/models/final.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "template": { 4 | "path": "cms/cms/status", 5 | "name": "Version Status" 6 | }, 7 | "route": "/cms/status", 8 | "state": "published", 9 | "layout": { 10 | "type": "Fields", 11 | "title": { 12 | "type": "Variants", 13 | "variants": { 14 | "*:*:en": "Lackey Status", 15 | "*:*:pl": "Status Lackey" 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /modules/core/test/server/models/fromyaml.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "template": { 4 | "path": "cms/cms/status", 5 | "name": "Version Status" 6 | }, 7 | "route": "/cms/status", 8 | "state": "published", 9 | "layout": { 10 | "type": "Fields", 11 | "title": { 12 | "type": "Variants", 13 | "variants": { 14 | "*:*:en": "Lackey Status", 15 | "*:*:pl": { 16 | "type": "doc", 17 | "content": [{ 18 | "type": "paragraph", 19 | "content": [{ 20 | "type": "text", 21 | "text": "Status Lackey" 22 | }] 23 | }] 24 | } 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /modules/core/test/server/models/tableB.json: -------------------------------------------------------------------------------- 1 | { 2 | "paging": { 3 | "total": 12333, 4 | "page": 1, 5 | "pages": 1234, 6 | "perPage": 10, 7 | "offset": 0, 8 | "sort" : { 9 | "myField" : 1, 10 | "otherField": -1 11 | }, 12 | "filters" : { 13 | "state" : "open" 14 | } 15 | }, 16 | "columns": [ 17 | { 18 | "label": "code", 19 | "type": "string", 20 | "name" : "code" 21 | }, 22 | { 23 | "label": "field", 24 | "type": "string", 25 | "name": "field" 26 | }, 27 | { 28 | "label": "other", 29 | "type": "string", 30 | "name": "other" 31 | } 32 | ], 33 | "rows": [ 34 | { 35 | "columns": [ 36 | { 37 | "value": "fr" 38 | }, 39 | { 40 | "value": "French field" 41 | }, 42 | { 43 | "value": false 44 | } 45 | ] 46 | }, 47 | { 48 | "columns": [ 49 | {}, 50 | { 51 | "value": "none" 52 | }, 53 | {} 54 | ] 55 | }, 56 | { 57 | "columns": [ 58 | { 59 | "value": "de" 60 | }, 61 | {}, 62 | { 63 | "value": true 64 | } 65 | ] 66 | } 67 | ] 68 | } 69 | -------------------------------------------------------------------------------- /modules/core/test/server/models/tableC.json: -------------------------------------------------------------------------------- 1 | { 2 | "paging": { 3 | "total": 12333, 4 | "page": 1, 5 | "pages": 1234, 6 | "perPage": 10, 7 | "offset": 0, 8 | "filters" : {} 9 | }, 10 | "columns": [ 11 | { 12 | "label": "code", 13 | "type": "string", 14 | "name": "code" 15 | }, 16 | { 17 | "label": "field", 18 | "type": "string", 19 | "name": "field" 20 | }, 21 | { 22 | "label": "other", 23 | "type": "string", 24 | "name": "other" 25 | } 26 | ], 27 | "rows": [ 28 | { 29 | "columns": [ 30 | { 31 | "value": "fr" 32 | }, 33 | { 34 | "value": "French field" 35 | }, 36 | { 37 | "value": false 38 | } 39 | ] 40 | }, 41 | { 42 | "columns": [ 43 | {}, 44 | { 45 | "value": "none" 46 | }, 47 | {} 48 | ] 49 | }, 50 | { 51 | "columns": [ 52 | { 53 | "value": "de" 54 | }, 55 | {}, 56 | { 57 | "value": true 58 | } 59 | ] 60 | } 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /modules/core/test/server/models/toyaml.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "page", 3 | "template": { 4 | "path": "cms/cms/status", 5 | "name": "Version Status" 6 | }, 7 | "route": "/cms/status", 8 | "state": "published", 9 | "layout": { 10 | "type": "Fields", 11 | "title": { 12 | "type": "Variants", 13 | "variants": { 14 | "*:*:en": { 15 | "type": "doc", 16 | "content": [{ 17 | "type": "paragraph", 18 | "content": [{ 19 | "type": "text", 20 | "text": "Lackey Status" 21 | }] 22 | }] 23 | }, 24 | "*:*:pl": { 25 | "type": "doc", 26 | "content": [{ 27 | "type": "paragraph", 28 | "content": [{ 29 | "type": "text", 30 | "text": "Status Lackey" 31 | }] 32 | }] 33 | } 34 | } 35 | 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /modules/i18n/module.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": [ 3 | ] 4 | } 5 | -------------------------------------------------------------------------------- /modules/i18n/server/routes/index.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | 'use strict'; 3 | /* 4 | Copyright 2016 Enigma Marketing Services Limited 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | const LanguageController = require('../controllers/language'); 19 | 20 | module.exports = (server) => { 21 | 22 | server.crud('/api/i18n/language', 'language', [server.acl], { 23 | list: LanguageController.list, 24 | create: LanguageController.create, 25 | read: LanguageController.read, 26 | update: LanguageController.update, 27 | delete: LanguageController.delete, 28 | byID: LanguageController.byId 29 | }); 30 | 31 | return Promise.resolve(); 32 | }; 33 | -------------------------------------------------------------------------------- /modules/users/client/js/forgot.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true */ 2 | 'use strict'; 3 | /* 4 | Copyright 2016 Enigma Marketing Services Limited 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | var 19 | lackey = require('core/client/js'), 20 | api = require('core/client/js/es5/api'), 21 | growl = require('core/client/js/es5/growl'); 22 | 23 | lackey.bind('lky:cms.account.forgot', 'submit', function (event, hook) { 24 | 25 | event.preventDefault(); 26 | event.stopPropagation(); 27 | 28 | var data = lackey.form(hook); 29 | 30 | api.create('/account/forgot-password', data).then(function () { 31 | growl({ 32 | status: 'success', 33 | message: 'Your reset link has been sent to: ' + data.username 34 | }); 35 | }, function () { 36 | growl({ 37 | status: 'error', 38 | message: 'Sorry, that user wasn\'t found!' 39 | }); 40 | }); 41 | 42 | return false; 43 | }); 44 | -------------------------------------------------------------------------------- /modules/users/client/js/login.js: -------------------------------------------------------------------------------- 1 | /* jslint browser:true, node:true */ 2 | 'use strict'; 3 | 4 | var 5 | form = document.querySelector('form'), 6 | growl = require('cms/client/js/growl'), 7 | xhr = require('core/client/js/xhr'), 8 | qs = require('query-string'); 9 | 10 | form.addEventListener('submit', function (event) { 11 | 12 | event.stopPropagation(); 13 | event.preventDefault(); 14 | 15 | var data = {}; 16 | 17 | Array.prototype.slice 18 | .apply(form.elements) 19 | .forEach(function (input) { 20 | if (!input.name || input.name === '') { 21 | return; 22 | } 23 | if (input.type === 'checkbox') { 24 | data[input.name] = input.checked ? input.value : null; 25 | } else { 26 | data[input.name] = input.value.trim(); 27 | } 28 | }); 29 | 30 | xhr 31 | .post('login', data) 32 | .then(function () { 33 | var query = qs.parse(document.location.search.replace(/^\?/, '')); 34 | if (query.return) { 35 | window.location.href = decodeURIComponent(query.return); 36 | return; 37 | } 38 | window.location.href = '/'; 39 | }, function () { 40 | growl({ 41 | message: 'Invalid credentials', 42 | status: 'error' 43 | }); 44 | }); 45 | 46 | }, null); 47 | -------------------------------------------------------------------------------- /modules/users/module.yml: -------------------------------------------------------------------------------- 1 | name : 'Lackey - Users' 2 | 3 | require: 4 | - 'cms/core' 5 | 6 | routes: 7 | /logout: 8 | get: 9 | controller: cms/users/server/controllers/login#logout 10 | 11 | /login: 12 | get: 13 | controller: cms/users/server/controllers/login#index 14 | post: 15 | controller: cms/users/server/controllers/login#login 16 | -------------------------------------------------------------------------------- /modules/users/server/auth/index.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | /* globals LACKEY_PATH */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | const SUtils = require(LACKEY_PATH).utils; 21 | 22 | module.exports.serializeUser = (user, done) => { 23 | done(null, user.id); 24 | }; 25 | 26 | module.exports.deserializeUser = (id, done) => { 27 | 28 | SUtils 29 | .cmsMod('core') 30 | .model('user') 31 | .then((user) => { 32 | return user.findById(id); 33 | }) 34 | .then((user) => { 35 | done(null, user); 36 | }, (error) => { 37 | done(error); 38 | }); 39 | }; 40 | -------------------------------------------------------------------------------- /modules/users/server/controllers/authentication.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/getlackey/lackey-cms/42e75b5f33d92c1cb98dee1067045942ce64f7f3/modules/users/server/controllers/authentication.js -------------------------------------------------------------------------------- /modules/users/server/lib/dust/role.js: -------------------------------------------------------------------------------- 1 | /* jslint node:true, esnext:true */ 2 | /* globals LACKEY_PATH */ 3 | 'use strict'; 4 | /* 5 | Copyright 2016 Enigma Marketing Services Limited 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | const SUtils = require(LACKEY_PATH).utils; 21 | 22 | let Role; 23 | 24 | SUtils 25 | .cmsMod('core') 26 | .model('role') 27 | .then((role) => { 28 | Role = role; 29 | }); 30 | 31 | 32 | /** 33 | * @param {DustEngine} dust 34 | */ 35 | module.exports = (dust) => { 36 | 37 | /** 38 | * Formats role to it's label 39 | * @param {Role} value 40 | * @returns {string} 41 | */ 42 | dust.filters.role = function (value) { 43 | 44 | if (!Role) return ''; 45 | 46 | if (Array.isArray(value)) { 47 | return value.map((role) => { 48 | return role.label; 49 | }).join(', '); 50 | } 51 | return value.label; 52 | }; 53 | 54 | }; 55 | -------------------------------------------------------------------------------- /modules/users/server/views/forgot-password.dust: -------------------------------------------------------------------------------- 1 | {>"cms/core/main"/} 2 | 3 | {