pageflow-external-links 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +19 -0
  3. data/.jshintignore +1 -0
  4. data/.jshintrc +22 -0
  5. data/Gemfile +10 -0
  6. data/README.md +49 -0
  7. data/Rakefile +7 -0
  8. data/app/assets/images/pageflow/external_links_pictogram.png +0 -0
  9. data/app/assets/images/pageflow/external_links_pictogram_small.png +0 -0
  10. data/app/assets/images/pageflow/ov-external_links.png +0 -0
  11. data/app/assets/javascript/pageflow/external_links.js +4 -0
  12. data/app/assets/javascript/pageflow/external_links/editor.js +12 -0
  13. data/app/assets/javascript/pageflow/external_links/editor/collections/site_references_collection.js +11 -0
  14. data/app/assets/javascript/pageflow/external_links/editor/collections/sites_collection.js +22 -0
  15. data/app/assets/javascript/pageflow/external_links/editor/config.js +17 -0
  16. data/app/assets/javascript/pageflow/external_links/editor/controllers/sidebar_controller.js +34 -0
  17. data/app/assets/javascript/pageflow/external_links/editor/models/configuration_mixin.js +38 -0
  18. data/app/assets/javascript/pageflow/external_links/editor/models/site.js +25 -0
  19. data/app/assets/javascript/pageflow/external_links/editor/models/site_file_selection_handler.js +13 -0
  20. data/app/assets/javascript/pageflow/external_links/editor/models/site_reference.js +7 -0
  21. data/app/assets/javascript/pageflow/external_links/editor/models/site_selection_handler.js +7 -0
  22. data/app/assets/javascript/pageflow/external_links/editor/routers/sidebar_router.js +8 -0
  23. data/app/assets/javascript/pageflow/external_links/editor/templates/edit_site.jst.ejs +10 -0
  24. data/app/assets/javascript/pageflow/external_links/editor/templates/embedded/list_item.jst.ejs +5 -0
  25. data/app/assets/javascript/pageflow/external_links/editor/templates/inputs/site_reference.jst.ejs +7 -0
  26. data/app/assets/javascript/pageflow/external_links/editor/templates/site_item.jst.ejs +6 -0
  27. data/app/assets/javascript/pageflow/external_links/editor/templates/site_reference_item.jst.ejs +6 -0
  28. data/app/assets/javascript/pageflow/external_links/editor/templates/sites.jst.ejs +1 -0
  29. data/app/assets/javascript/pageflow/external_links/editor/templates/sites_blank_slate.jst.ejs +1 -0
  30. data/app/assets/javascript/pageflow/external_links/editor/views/configuration_editor.js +23 -0
  31. data/app/assets/javascript/pageflow/external_links/editor/views/edit_site_view.js +69 -0
  32. data/app/assets/javascript/pageflow/external_links/editor/views/embedded/list_embedded_view.js +22 -0
  33. data/app/assets/javascript/pageflow/external_links/editor/views/embedded/list_item_embedded_view.js +56 -0
  34. data/app/assets/javascript/pageflow/external_links/editor/views/inputs/site_reference_input_view.js +31 -0
  35. data/app/assets/javascript/pageflow/external_links/editor/views/site_item_view.js +44 -0
  36. data/app/assets/javascript/pageflow/external_links/editor/views/site_reference_item_view.js +32 -0
  37. data/app/assets/javascript/pageflow/external_links/editor/views/sites_view.js +35 -0
  38. data/app/assets/javascript/pageflow/external_links/page_type.js +141 -0
  39. data/app/assets/stylesheets/pageflow/external_links.css.scss +175 -0
  40. data/app/assets/stylesheets/pageflow/external_links/editor.css.scss +97 -0
  41. data/app/controllers/pageflow/external_links/sites_controller.rb +40 -0
  42. data/app/helpers/pageflow/external_links/sites_helper.rb +9 -0
  43. data/app/models/pageflow/external_links/site.rb +7 -0
  44. data/app/views/pageflow/external_links/page.html +34 -0
  45. data/app/views/pageflow/external_links/sites/_site.html.erb +10 -0
  46. data/config/locales/de.yml +21 -0
  47. data/config/routes.rb +5 -0
  48. data/db/migrate/20140616153235_create_pageflow_external_links_sites.rb +16 -0
  49. data/lib/pageflow-external-links.rb +6 -0
  50. data/lib/pageflow/external_links/engine.rb +18 -0
  51. data/lib/pageflow/external_links/page_type.rb +15 -0
  52. data/pageflow-external-links.gemspec +27 -0
  53. metadata +193 -0
@@ -0,0 +1,22 @@
1
+ pageflow.externalLinks.ListEmbeddedView = Backbone.Marionette.View.extend({
2
+ render: function() {
3
+ this.subview(new pageflow.CollectionView({
4
+ el: this.$el.find('div'),
5
+ collection: this.model.externalSiteReferences(),
6
+ itemViewConstructor: pageflow.externalLinks.ListItemEmbeddedView
7
+ }));
8
+
9
+ this.listenTo(this.model.externalSiteReferences(), 'add remove', function() {
10
+ this.refreshScroller();
11
+ });
12
+
13
+ this.refreshScroller();
14
+
15
+ return this;
16
+ },
17
+
18
+ refreshScroller: function() {
19
+ this.$el.data('scroller').refresh();
20
+ this.$el.data('scroller').checkDisable();
21
+ }
22
+ });
@@ -0,0 +1,56 @@
1
+ pageflow.externalLinks.ListItemEmbeddedView = Backbone.Marionette.ItemView.extend({
2
+ template: 'pageflow/external_links/editor/templates/embedded/list_item',
3
+
4
+ tagName: 'a',
5
+ className: 'link-item',
6
+
7
+ ui: {
8
+ title: '.link-title',
9
+ description: '.link-description',
10
+ thumbnail: '.link-thumbnail'
11
+ },
12
+
13
+ onRender: function() {
14
+ this.listenTo(this.model.get('site'), 'change', this.update);
15
+ this.update();
16
+ },
17
+
18
+ update: function() {
19
+ var site = this.model.get('site');
20
+
21
+ this.ui.title.text(site.get('title'));
22
+ this.ui.description.html(site.get('description'));
23
+
24
+ this.$el.toggleClass('no_text', blank(site.get('title')) && blank(site.get('description')));
25
+
26
+ this.$el.attr('href', site.get('url'));
27
+ this.$el.attr('blank', site.get('open_in_new_tab') ? '_blank' : null);
28
+
29
+ this.updateThumbnailView(site);
30
+
31
+ function blank(text) {
32
+ return !text || text.replace(/\s+/g, '').replace(/ /g, '') === '';
33
+ }
34
+ },
35
+
36
+ updateThumbnailView: function(site) {
37
+ var thumbnail = site.getThumbnail();
38
+
39
+ if (this.currentThumbnail !== thumbnail) {
40
+ this.currentThumbnail = thumbnail;
41
+
42
+ if (this.thumbnailView) {
43
+ this.thumbnailView.close();
44
+ }
45
+
46
+ if (thumbnail) {
47
+ this.thumbnailView = this.subview(new pageflow.FileThumbnailView({
48
+ model: thumbnail,
49
+ imageUrlPropertyName: 'link_thumbnail_url'
50
+ }));
51
+
52
+ this.ui.thumbnail.append(this.thumbnailView.el);
53
+ }
54
+ }
55
+ },
56
+ });
@@ -0,0 +1,31 @@
1
+ pageflow.externalLinks.SiteReferenceInputView = Backbone.Marionette.ItemView.extend({
2
+ mixins: [pageflow.inputView],
3
+
4
+ template: 'pageflow/external_links/editor/templates/inputs/site_reference',
5
+ className: 'external_links_site_reference_input',
6
+
7
+ ui: {
8
+ sites: 'ul.sites'
9
+ },
10
+
11
+ events: {
12
+ 'click .add_reference': function() {
13
+ pageflow.editor.navigate(
14
+ '/external_links/sites?page=' + this.model.page.id,
15
+ {trigger: true}
16
+ );
17
+ return false;
18
+ }
19
+ },
20
+
21
+ onRender: function() {
22
+ this.subview(new pageflow.SortableCollectionView({
23
+ el: this.ui.sites,
24
+ collection: this.model.externalSiteReferences(),
25
+ itemViewConstructor: pageflow.externalLinks.SiteReferenceItemView,
26
+ itemViewOptions: {
27
+ page: this.model.page
28
+ }
29
+ }));
30
+ }
31
+ });
@@ -0,0 +1,44 @@
1
+ pageflow.externalLinks.SiteItemView = Backbone.Marionette.ItemView.extend({
2
+ tagName: 'li',
3
+ template: 'pageflow/external_links/editor/templates/site_item',
4
+
5
+ mixins: [pageflow.loadable],
6
+
7
+ ui: {
8
+ title: '.title',
9
+ selectButton: '.select',
10
+ thumbnail: '.thumbnail'
11
+ },
12
+
13
+ events: {
14
+ 'click': function() {
15
+ if (!this.model.isNew()) {
16
+ var query = this.options.page ? '/?page=' + this.options.page.id + '&return_to=sites' : '';
17
+ pageflow.editor.navigate('/external_links/sites/' + this.model.get('id') + query, {trigger: true});
18
+ }
19
+ return false;
20
+ },
21
+
22
+ 'click .select': function() {
23
+ if (this.options.selectionHandler) {
24
+ this.options.selectionHandler.call(this.model);
25
+ pageflow.editor.navigate(this.options.referer, {trigger: true});
26
+ }
27
+ return false;
28
+ }
29
+ },
30
+
31
+ onRender: function() {
32
+ this.update();
33
+
34
+ this.subview(new pageflow.FileThumbnailView({
35
+ el: this.ui.thumbnail,
36
+ model: this.model.getReference('thumbnail', pageflow.imageFiles)
37
+ }));
38
+ },
39
+
40
+ update: function() {
41
+ this.ui.title.text(this.model.get('title') || '(Unbenannt)');
42
+ this.ui.selectButton.toggle(!!this.options.selectionHandler);
43
+ }
44
+ });
@@ -0,0 +1,32 @@
1
+ pageflow.externalLinks.SiteReferenceItemView = Backbone.Marionette.ItemView.extend({
2
+ template: 'pageflow/external_links/editor/templates/site_reference_item',
3
+
4
+ tagName: 'li',
5
+ className: 'external_links_site_reference',
6
+
7
+ ui: {
8
+ thumbnail: '.thumbnail',
9
+ title: '.title'
10
+ },
11
+
12
+ events: {
13
+ 'click .remove': function() {
14
+ this.model.destroy();
15
+ return false;
16
+ },
17
+
18
+ 'click .edit': function() {
19
+ pageflow.editor.navigate('/external_links/sites/' + this.model.get('site').id + '/?page=' + this.options.page.id + '&return_to=page', {trigger: true});
20
+ return false;
21
+ }
22
+ },
23
+
24
+ onRender: function() {
25
+ this.subview(new pageflow.FileThumbnailView({
26
+ el: this.ui.thumbnail,
27
+ model: this.model.get('site').getThumbnail()
28
+ }));
29
+
30
+ this.ui.title.text(this.model.get('site').get('title') || '(Unbenannt)');
31
+ },
32
+ });
@@ -0,0 +1,35 @@
1
+ pageflow.externalLinks.SitesView = Backbone.Marionette.ItemView.extend({
2
+ className: 'manage_external_sites',
3
+ template: 'pageflow/external_links/editor/templates/sites',
4
+
5
+ events: {
6
+ 'click .add': function() {
7
+ var site = pageflow.externalLinks.sites.create({title: ''});
8
+ var options = this.options;
9
+
10
+ site.once('sync', function() {
11
+ var query = options.page ? '/?page=' + options.page.id + '&return_to=sites' : '';
12
+ pageflow.editor.navigate('external_links/sites/' + site.id + query, {trigger: true});
13
+ });
14
+ }
15
+ },
16
+
17
+ onRender: function() {
18
+ pageflow.externalLinks.sites.ensureFetched();
19
+
20
+ this.$el.append(this.subview(new pageflow.CollectionView({
21
+ tagName: 'ul',
22
+ className: 'sites',
23
+ collection: pageflow.externalLinks.sites,
24
+ itemViewConstructor: pageflow.externalLinks.SiteItemView,
25
+ itemViewOptions: {
26
+ selectionHandler: this.options.selectionHandler,
27
+ referer: this.options.referer,
28
+ page: this.options.page
29
+ },
30
+ blankSlateViewConstructor: Backbone.Marionette.ItemView.extend({
31
+ template: 'pageflow/external_links/editor/templates/sites_blank_slate'
32
+ })
33
+ })).el);
34
+ }
35
+ });
@@ -0,0 +1,141 @@
1
+ /*global IScroll*/
2
+
3
+ pageflow.pageType.register('external_links', _.extend({
4
+ prepareNextPageTimeout: 0,
5
+
6
+ enhance: function(pageElement, configuration) {
7
+ var scrollerElement = pageElement.find('.ext-links'),
8
+ that = this,
9
+ innerScroller = pageElement.find('#horizontal_scroller'),
10
+ contentWrapper = pageElement.find('.contentWrapper');
11
+
12
+ this.scroller = new IScroll(scrollerElement[0], {
13
+ mouseWheel: true,
14
+ bounce: false,
15
+ keyBindings: true,
16
+ scrollX: true,
17
+ scrollY: false,
18
+ probeType: 2,
19
+ eventPassthrough: true
20
+ });
21
+
22
+ this.scroller.checkDisable = function() {
23
+ that._checkForIScroll(scrollerElement, innerScroller, pageElement.find('.arrow-forward'), pageElement.find('.arrow-back'), pageElement);
24
+ };
25
+ scrollerElement.data('scroller', this.scroller);
26
+
27
+ that.scroller.on('scroll', function() {
28
+ that.scroller.checkDisable();
29
+ });
30
+
31
+
32
+ /* Arrows for Gallery */
33
+
34
+ pageElement.find('.arrow-back').on('click', function(e) {
35
+ var nextElement = Math.round((that.scroller.x / - 260) - (scrollerElement.width() / 260 / 2), 10);
36
+ if(nextElement <= 1 ) {
37
+ that.scroller.scrollTo(0, 0, 500, IScroll.ease.quadratic);
38
+ }
39
+ else {
40
+ that.scroller.scrollToElement($(".page.active #horizontal_scroller a")[nextElement], 500, 0, 0, IScroll.ease.quadratic);
41
+ }
42
+ that.scroller.checkDisable();
43
+ e.stopPropagation();
44
+ return false;
45
+ });
46
+
47
+ pageElement.find('.arrow-forward').on('click', function(e) {
48
+ var nextElement = Math.round((that.scroller.x / - 260) + (scrollerElement.width() / 260 / 2), 10);
49
+ if(nextElement == innerScroller.find('a').length -1 ) {
50
+ that.scroller.scrollTo(that.scroller.maxScrollX, 0, 500, IScroll.ease.quadratic);
51
+ }
52
+ else {
53
+ that.scroller.scrollToElement($(".page.active #horizontal_scroller a")[nextElement]);
54
+ }
55
+ that.scroller.checkDisable();
56
+ e.stopPropagation();
57
+ return false;
58
+ });
59
+ },
60
+
61
+ resize: function(pageElement, configuration) {
62
+ this.scroller.refresh();
63
+ this.scroller.checkDisable();
64
+ },
65
+
66
+ _checkForIScroll: function(outerElement, innerElement, arrowForward, arrowBack, pageElement) {
67
+ if(pageElement.width() <= 700) {
68
+ this.scroller.disable();
69
+ }
70
+ else {
71
+ if(innerElement.width() <= outerElement.width()) {
72
+ this.scroller.disable();
73
+ arrowForward.css('display','none');
74
+ arrowBack.css('display','none');
75
+ }
76
+ else {
77
+ this.scroller.enable();
78
+ if(this.scroller.x == this.scroller.maxScrollX) {
79
+ arrowForward.css('display','none');
80
+ }
81
+ else {
82
+ arrowForward.css('display','block');
83
+ }
84
+ if(this.scroller.x === 0) {
85
+ arrowBack.css('display','none');
86
+ }
87
+ else {
88
+ arrowBack.css('display','block');
89
+ }
90
+ }
91
+ }
92
+ },
93
+
94
+ prepare: function(pageElement, configuration) {
95
+ },
96
+
97
+ preload: function(pageElement, configuration) {
98
+ return pageflow.preload.backgroundImage(pageElement.find('.background_image'));
99
+ },
100
+
101
+ activating: function(pageElement, configuration) {
102
+ this.scroller.refresh();
103
+ this.scroller.checkDisable();
104
+ },
105
+
106
+ activated: function(pageElement, configuration) {
107
+ },
108
+
109
+ deactivating: function(pageElement, configuration) {},
110
+
111
+ deactivated: function(pageElement, configuration) {},
112
+
113
+ update: function(pageElement, configuration) {
114
+ pageElement.find('h2 .tagline').text(configuration.get('tagline') || '');
115
+ pageElement.find('h2 .title').text(configuration.get('title') || '');
116
+ pageElement.find('h2 .subtitle').text(configuration.get('subtitle') || '');
117
+ pageElement.find('.contentText p').html(configuration.get('text') || '');
118
+
119
+ this.updateCommonPageCssClasses(pageElement, configuration);
120
+
121
+ pageElement.find('.shadow').css({
122
+ opacity: configuration.get('gradient_opacity') / 100
123
+ });
124
+ this.scroller.refresh();
125
+ this.scroller.checkDisable();
126
+ },
127
+
128
+ embeddedEditorViews: function() {
129
+ return {
130
+ '.background_image': {
131
+ view: pageflow.BackgroundImageEmbeddedView,
132
+ options: {propertyName: 'background_image_id'}
133
+ },
134
+
135
+ '.ext-links': {
136
+ view: pageflow.externalLinks.ListEmbeddedView,
137
+ options: {propertyName: 'linked_external_site_perma_ids'}
138
+ }
139
+ };
140
+ }
141
+ }, pageflow.commonPageCssClasses));
@@ -0,0 +1,175 @@
1
+ @include pageflow-page-type(external_links);
2
+
3
+ .external-links-page {
4
+
5
+ .ext-links {
6
+ height: 400px;
7
+ pointer-events: all;
8
+ position: relative;
9
+ @include transition(opacity 0.5s);
10
+
11
+ .hideText & {
12
+ @include transform(translate(-100%,0));
13
+ }
14
+
15
+ @include phone {
16
+ height: auto;
17
+ }
18
+ }
19
+
20
+ .arrow-forward, .arrow-back {
21
+ position: relative;
22
+ top: 100%;
23
+ width: 80px;
24
+ height: 80px;
25
+ text-decoration: none;
26
+ pointer-events: all;
27
+
28
+ &:before {
29
+ content: "\f105";
30
+ font-family: "FontAwesome";
31
+ color: white;
32
+ width: 100%;
33
+ position: absolute;
34
+ height: 100%;
35
+ text-align: center;
36
+ line-height: 80px;
37
+ font-size: 80px;
38
+ opacity: 0.9;
39
+ text-shadow: 2px 2px 7px black, -1px -1px 7px black;
40
+ @include transition(opacity 0.3s);
41
+ }
42
+
43
+ &:hover {
44
+ &:before {
45
+ opacity: 1;
46
+ }
47
+ }
48
+
49
+ .invert & {
50
+ &:before {
51
+ color: black;
52
+ text-shadow: 2px 2px 7px black, -1px -1px 7px white;
53
+ }
54
+ }
55
+
56
+
57
+ @include phone {
58
+ display: none !important;
59
+ }
60
+ }
61
+
62
+ .arrow-back {
63
+
64
+ &:before {
65
+ content: "\f104";
66
+ }
67
+ }
68
+ .arrow-forward {
69
+ float: right;
70
+ }
71
+
72
+ #horizontal_scroller {
73
+ position: absolute;
74
+ text-align: center;
75
+
76
+ .js & {
77
+ white-space: nowrap;
78
+
79
+ @include phone {
80
+ white-space: normal;
81
+ position: relative;
82
+ }
83
+ }
84
+
85
+ @include phone {
86
+ white-space: normal;
87
+ position: relative;
88
+ }
89
+ }
90
+
91
+ .link-item {
92
+ display: inline-block;
93
+ width: 24%;
94
+ width: 250px;
95
+ background-color: rgb(20,20,20);
96
+ background-color: rgba(20,20,20, 0.8);
97
+ vertical-align: top;
98
+ max-height: 400px;
99
+ height: 400px;
100
+ overflow: hidden;
101
+ text-align: left;
102
+ margin-right: 10px;
103
+ text-decoration: none;
104
+ color: white;
105
+ @include transition(0.3s);
106
+
107
+ &.no_text {
108
+ height: auto;
109
+
110
+ .link-details {
111
+ display: none;
112
+ }
113
+ }
114
+
115
+ &:hover {
116
+ text-decoration: underline;
117
+ background-color: rgba(20,20,20, 1);
118
+ @include transform(scale(1.05));
119
+
120
+ @include phone {
121
+ @include transform(scale(1));
122
+ }
123
+ }
124
+ @include phone {
125
+ width: 230px;
126
+ margin-right: 0;
127
+ margin-bottom: 10px;
128
+ height: 290px;
129
+ max-height: 290px;
130
+ margin-right: 5px;
131
+ margin-left: 5px;
132
+ }
133
+
134
+ &:last-child {
135
+ }
136
+
137
+ .link-thumbnail {
138
+ background-repeat: no-repeat;
139
+ background-size: cover;
140
+ width: 100%;
141
+ padding-top: 56.25%;
142
+ position: relative;
143
+
144
+ .file_thumbnail {
145
+ background-size: cover;
146
+ position: absolute;
147
+ top: 0;
148
+ left: 0;
149
+ bottom: 0;
150
+ right: 0;
151
+ }
152
+ }
153
+
154
+ .link-details {
155
+ margin: 20px;
156
+ text-decoration: none;
157
+ color: #fff;
158
+
159
+ p {
160
+ width: 100%;
161
+ white-space: normal;
162
+ line-height: 1.3em;
163
+ }
164
+
165
+ .link-title {
166
+ font-size: 1.2em;
167
+ font-weight: bold;
168
+ text-overflow: ellipsis;
169
+ width: 100%;
170
+ white-space: nowrap;
171
+ overflow: hidden;
172
+ }
173
+ }
174
+ }
175
+ }