├── .gitignore └── using-vuejs-in-front-of-drupal-8 ├── README.md ├── build └── build.js ├── css ├── base.css ├── code.css ├── grids.css ├── home.css ├── main.css ├── menus.css ├── posts.css └── reset.css ├── drupal └── modules │ └── api │ ├── api.info.yml │ ├── api.module │ └── src │ └── Plugin │ └── Rest │ └── Resource │ ├── v1_0 │ ├── ArticleBundleResource.php │ └── BaseBundleResource.php │ └── v2_0 │ ├── ArticleBundleResource.php │ └── BaseBundleResource.php ├── index.html ├── package.json └── src ├── app.js ├── app.vue └── views └── article-view.vue /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea 3 | node_modules -------------------------------------------------------------------------------- /using-vuejs-in-front-of-drupal-8/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/briward/examples/a68a164b6ea0dfe9a5bf587b71a7a543ea849fe0/using-vuejs-in-front-of-drupal-8/README.md -------------------------------------------------------------------------------- /using-vuejs-in-front-of-drupal-8/css/base.css: -------------------------------------------------------------------------------- 1 | /** 2 | *--------------------------------------------------------- 3 | * Base styles 4 | *--------------------------------------------------------- 5 | */ 6 | 7 | @import url(http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600,700,400italic); 8 | @import url(http://fonts.googleapis.com/css?family=Montserrat:700,400); 9 | 10 | * { 11 | -moz-box-sizing:border-box; 12 | -webkit-box-sizing:border-box; 13 | box-sizing:border-box; 14 | } 15 | 16 | html { 17 | font-size: 100%; 18 | } 19 | body { 20 | font-family: "freight-sans-pro",sans-serif; 21 | font-size: 1.4rem; 22 | color: #454d57; 23 | background:#13222D; 24 | -webkit-font-smoothing: antialiased; 25 | } 26 | 27 | html, button, input, select, textarea, 28 | .pure-g [class *= "pure-u"] { 29 | /* Set your content font stack here: */ 30 | font-family: "freight-sans-pro",sans-serif; 31 | } 32 | 33 | h1, h2, h3, h4 { 34 | font-family: "jaf-domus-titling-web",sans-serif; 35 | font-weight:400; 36 | } 37 | 38 | h1 { 39 | font-size: 3rem; 40 | line-height: 3.2rem; 41 | margin: 0 0 2rem; 42 | color:#E92E59; 43 | } 44 | 45 | h2 { 46 | line-height:2rem; 47 | } 48 | 49 | a { 50 | color:#E92E59; 51 | text-decoration:none; 52 | } 53 | a:hover { 54 | text-decoration:underline; 55 | } 56 | 57 | p { 58 | font-size: 1.25rem; 59 | margin: 0 0 2rem; 60 | line-height: 1.6em; 61 | } 62 | em { 63 | font-style:italic; 64 | } 65 | div.post.full p:first-of-type:first-letter { 66 | text-transform:uppercase; 67 | font-family: "jaf-domus-titling-web",sans-serif; 68 | font-weight:400; 69 | font-size:4.2rem; 70 | float: left; 71 | margin: 0 6px 0 0; 72 | color:#E92E59; 73 | line-height: 0.6; 74 | text-align: center; 75 | } 76 | code { 77 | background:#f2f2f2; 78 | padding:3px 5px; 79 | -moz-border-radius:4px; 80 | -webkit-border-radius:4px; 81 | border-radius:4px; 82 | font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; 83 | line-height:1.8rem; 84 | font-size:0.875rem; 85 | color:rgb(51,51,51); 86 | } 87 | -------------------------------------------------------------------------------- /using-vuejs-in-front-of-drupal-8/css/code.css: -------------------------------------------------------------------------------- 1 | /* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript */ 2 | /** 3 | * prism.js default theme for JavaScript, CSS and HTML 4 | * Based on dabblet (http://dabblet.com) 5 | * @author Lea Verou 6 | */ 7 | 8 | code[class*="language-"], 9 | pre[class*="language-"] { 10 | color: black; 11 | text-shadow: 0 1px white; 12 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 13 | direction: ltr; 14 | text-align: left; 15 | white-space: pre; 16 | word-spacing: normal; 17 | word-break: normal; 18 | line-height: 1.5; 19 | 20 | -moz-tab-size: 4; 21 | -o-tab-size: 4; 22 | tab-size: 4; 23 | 24 | -webkit-hyphens: none; 25 | -moz-hyphens: none; 26 | -ms-hyphens: none; 27 | hyphens: none; 28 | } 29 | 30 | pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, 31 | code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { 32 | text-shadow: none; 33 | background: #b3d4fc; 34 | } 35 | 36 | pre[class*="language-"]::selection, pre[class*="language-"] ::selection, 37 | code[class*="language-"]::selection, code[class*="language-"] ::selection { 38 | text-shadow: none; 39 | background: #b3d4fc; 40 | } 41 | 42 | @media print { 43 | code[class*="language-"], 44 | pre[class*="language-"] { 45 | text-shadow: none; 46 | } 47 | } 48 | 49 | /* Code blocks */ 50 | pre[class*="language-"] { 51 | padding: 1em; 52 | margin: .5em 0; 53 | overflow: auto; 54 | } 55 | 56 | :not(pre) > code[class*="language-"], 57 | pre[class*="language-"] { 58 | background: #f5f2f0; 59 | } 60 | 61 | /* Inline code */ 62 | :not(pre) > code[class*="language-"] { 63 | padding: .1em; 64 | border-radius: .3em; 65 | } 66 | 67 | .token.comment, 68 | .token.prolog, 69 | .token.doctype, 70 | .token.cdata { 71 | color: slategray; 72 | } 73 | 74 | .token.punctuation { 75 | color: #999; 76 | } 77 | 78 | .namespace { 79 | opacity: .7; 80 | } 81 | 82 | .token.property, 83 | .token.tag, 84 | .token.boolean, 85 | .token.number, 86 | .token.constant, 87 | .token.symbol, 88 | .token.deleted { 89 | color: #905; 90 | } 91 | 92 | .token.selector, 93 | .token.attr-name, 94 | .token.string, 95 | .token.char, 96 | .token.builtin, 97 | .token.inserted { 98 | color: #690; 99 | } 100 | 101 | .token.operator, 102 | .token.entity, 103 | .token.url, 104 | .language-css .token.string, 105 | .style .token.string { 106 | color: #a67f59; 107 | background: hsla(0, 0%, 100%, .5); 108 | } 109 | 110 | .token.atrule, 111 | .token.attr-value, 112 | .token.keyword { 113 | color: #07a; 114 | } 115 | 116 | .token.function { 117 | color: #DD4A68; 118 | } 119 | 120 | .token.regex, 121 | .token.important, 122 | .token.variable { 123 | color: #e90; 124 | } 125 | 126 | .token.important, 127 | .token.bold { 128 | font-weight: bold; 129 | } 130 | .token.italic { 131 | font-style: italic; 132 | } 133 | 134 | .token.entity { 135 | cursor: help; 136 | } -------------------------------------------------------------------------------- /using-vuejs-in-front-of-drupal-8/css/grids.css: -------------------------------------------------------------------------------- 1 | /*! 2 | Pure v0.5.0 3 | Copyright 2014 Yahoo! Inc. All rights reserved. 4 | Licensed under the BSD License. 5 | https://github.com/yui/pure/blob/master/LICENSE.md 6 | */ 7 | .pure-g{letter-spacing:-.31em;*letter-spacing:normal;*word-spacing:-.43em;text-rendering:optimizespeed;font-family:FreeSans,Arimo,"Droid Sans",Helvetica,Arial,sans-serif;display:-webkit-flex;-webkit-flex-flow:row wrap;display:-ms-flexbox;-ms-flex-flow:row wrap}.opera-only :-o-prefocus,.pure-g{word-spacing:-.43em}.pure-u{display:inline-block;*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-g [class *="pure-u"]{font-family:sans-serif}.pure-u-1,.pure-u-1-1,.pure-u-1-2,.pure-u-1-3,.pure-u-2-3,.pure-u-1-4,.pure-u-3-4,.pure-u-1-5,.pure-u-2-5,.pure-u-3-5,.pure-u-4-5,.pure-u-5-5,.pure-u-1-6,.pure-u-5-6,.pure-u-1-8,.pure-u-3-8,.pure-u-5-8,.pure-u-7-8,.pure-u-1-12,.pure-u-5-12,.pure-u-7-12,.pure-u-11-12,.pure-u-1-24,.pure-u-2-24,.pure-u-3-24,.pure-u-4-24,.pure-u-5-24,.pure-u-6-24,.pure-u-7-24,.pure-u-8-24,.pure-u-9-24,.pure-u-10-24,.pure-u-11-24,.pure-u-12-24,.pure-u-13-24,.pure-u-14-24,.pure-u-15-24,.pure-u-16-24,.pure-u-17-24,.pure-u-18-24,.pure-u-19-24,.pure-u-20-24,.pure-u-21-24,.pure-u-22-24,.pure-u-23-24,.pure-u-24-24{display:inline-block;*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-1-24{width:4.1667%;*width:4.1357%}.pure-u-1-12,.pure-u-2-24{width:8.3333%;*width:8.3023%}.pure-u-1-8,.pure-u-3-24{width:12.5%;*width:12.469%}.pure-u-1-6,.pure-u-4-24{width:16.6667%;*width:16.6357%}.pure-u-1-5{width:20%;*width:19.969%}.pure-u-5-24{width:20.8333%;*width:20.8023%}.pure-u-1-4,.pure-u-6-24{width:25%;*width:24.969%}.pure-u-7-24{width:29.1667%;*width:29.1357%}.pure-u-1-3,.pure-u-8-24{width:33.3333%;*width:33.3023%}.pure-u-3-8,.pure-u-9-24{width:37.5%;*width:37.469%}.pure-u-2-5{width:40%;*width:39.969%}.pure-u-5-12,.pure-u-10-24{width:41.6667%;*width:41.6357%}.pure-u-11-24{width:45.8333%;*width:45.8023%}.pure-u-1-2,.pure-u-12-24{width:50%;*width:49.969%}.pure-u-13-24{width:54.1667%;*width:54.1357%}.pure-u-7-12,.pure-u-14-24{width:58.3333%;*width:58.3023%}.pure-u-3-5{width:60%;*width:59.969%}.pure-u-5-8,.pure-u-15-24{width:62.5%;*width:62.469%}.pure-u-2-3,.pure-u-16-24{width:66.6667%;*width:66.6357%}.pure-u-17-24{width:70.8333%;*width:70.8023%}.pure-u-3-4,.pure-u-18-24{width:75%;*width:74.969%}.pure-u-19-24{width:79.1667%;*width:79.1357%}.pure-u-4-5{width:80%;*width:79.969%}.pure-u-5-6,.pure-u-20-24{width:83.3333%;*width:83.3023%}.pure-u-7-8,.pure-u-21-24{width:87.5%;*width:87.469%}.pure-u-11-12,.pure-u-22-24{width:91.6667%;*width:91.6357%}.pure-u-23-24{width:95.8333%;*width:95.8023%}.pure-u-1,.pure-u-1-1,.pure-u-5-5,.pure-u-24-24{width:100%}/*! 8 | Pure v0.5.0 9 | Copyright 2014 Yahoo! Inc. All rights reserved. 10 | Licensed under the BSD License. 11 | https://github.com/yui/pure/blob/master/LICENSE.md 12 | */ 13 | @media screen and (min-width:35.5em){.pure-u-sm-1,.pure-u-sm-1-1,.pure-u-sm-1-2,.pure-u-sm-1-3,.pure-u-sm-2-3,.pure-u-sm-1-4,.pure-u-sm-3-4,.pure-u-sm-1-5,.pure-u-sm-2-5,.pure-u-sm-3-5,.pure-u-sm-4-5,.pure-u-sm-5-5,.pure-u-sm-1-6,.pure-u-sm-5-6,.pure-u-sm-1-8,.pure-u-sm-3-8,.pure-u-sm-5-8,.pure-u-sm-7-8,.pure-u-sm-1-12,.pure-u-sm-5-12,.pure-u-sm-7-12,.pure-u-sm-11-12,.pure-u-sm-1-24,.pure-u-sm-2-24,.pure-u-sm-3-24,.pure-u-sm-4-24,.pure-u-sm-5-24,.pure-u-sm-6-24,.pure-u-sm-7-24,.pure-u-sm-8-24,.pure-u-sm-9-24,.pure-u-sm-10-24,.pure-u-sm-11-24,.pure-u-sm-12-24,.pure-u-sm-13-24,.pure-u-sm-14-24,.pure-u-sm-15-24,.pure-u-sm-16-24,.pure-u-sm-17-24,.pure-u-sm-18-24,.pure-u-sm-19-24,.pure-u-sm-20-24,.pure-u-sm-21-24,.pure-u-sm-22-24,.pure-u-sm-23-24,.pure-u-sm-24-24{display:inline-block;*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-sm-1-24{width:4.1667%;*width:4.1357%}.pure-u-sm-1-12,.pure-u-sm-2-24{width:8.3333%;*width:8.3023%}.pure-u-sm-1-8,.pure-u-sm-3-24{width:12.5%;*width:12.469%}.pure-u-sm-1-6,.pure-u-sm-4-24{width:16.6667%;*width:16.6357%}.pure-u-sm-1-5{width:20%;*width:19.969%}.pure-u-sm-5-24{width:20.8333%;*width:20.8023%}.pure-u-sm-1-4,.pure-u-sm-6-24{width:25%;*width:24.969%}.pure-u-sm-7-24{width:29.1667%;*width:29.1357%}.pure-u-sm-1-3,.pure-u-sm-8-24{width:33.3333%;*width:33.3023%}.pure-u-sm-3-8,.pure-u-sm-9-24{width:37.5%;*width:37.469%}.pure-u-sm-2-5{width:40%;*width:39.969%}.pure-u-sm-5-12,.pure-u-sm-10-24{width:41.6667%;*width:41.6357%}.pure-u-sm-11-24{width:45.8333%;*width:45.8023%}.pure-u-sm-1-2,.pure-u-sm-12-24{width:50%;*width:49.969%}.pure-u-sm-13-24{width:54.1667%;*width:54.1357%}.pure-u-sm-7-12,.pure-u-sm-14-24{width:58.3333%;*width:58.3023%}.pure-u-sm-3-5{width:60%;*width:59.969%}.pure-u-sm-5-8,.pure-u-sm-15-24{width:62.5%;*width:62.469%}.pure-u-sm-2-3,.pure-u-sm-16-24{width:66.6667%;*width:66.6357%}.pure-u-sm-17-24{width:70.8333%;*width:70.8023%}.pure-u-sm-3-4,.pure-u-sm-18-24{width:75%;*width:74.969%}.pure-u-sm-19-24{width:79.1667%;*width:79.1357%}.pure-u-sm-4-5{width:80%;*width:79.969%}.pure-u-sm-5-6,.pure-u-sm-20-24{width:83.3333%;*width:83.3023%}.pure-u-sm-7-8,.pure-u-sm-21-24{width:87.5%;*width:87.469%}.pure-u-sm-11-12,.pure-u-sm-22-24{width:91.6667%;*width:91.6357%}.pure-u-sm-23-24{width:95.8333%;*width:95.8023%}.pure-u-sm-1,.pure-u-sm-1-1,.pure-u-sm-5-5,.pure-u-sm-24-24{width:100%}}@media screen and (min-width:48em){.pure-u-md-1,.pure-u-md-1-1,.pure-u-md-1-2,.pure-u-md-1-3,.pure-u-md-2-3,.pure-u-md-1-4,.pure-u-md-3-4,.pure-u-md-1-5,.pure-u-md-2-5,.pure-u-md-3-5,.pure-u-md-4-5,.pure-u-md-5-5,.pure-u-md-1-6,.pure-u-md-5-6,.pure-u-md-1-8,.pure-u-md-3-8,.pure-u-md-5-8,.pure-u-md-7-8,.pure-u-md-1-12,.pure-u-md-5-12,.pure-u-md-7-12,.pure-u-md-11-12,.pure-u-md-1-24,.pure-u-md-2-24,.pure-u-md-3-24,.pure-u-md-4-24,.pure-u-md-5-24,.pure-u-md-6-24,.pure-u-md-7-24,.pure-u-md-8-24,.pure-u-md-9-24,.pure-u-md-10-24,.pure-u-md-11-24,.pure-u-md-12-24,.pure-u-md-13-24,.pure-u-md-14-24,.pure-u-md-15-24,.pure-u-md-16-24,.pure-u-md-17-24,.pure-u-md-18-24,.pure-u-md-19-24,.pure-u-md-20-24,.pure-u-md-21-24,.pure-u-md-22-24,.pure-u-md-23-24,.pure-u-md-24-24{display:inline-block;*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-md-1-24{width:4.1667%;*width:4.1357%}.pure-u-md-1-12,.pure-u-md-2-24{width:8.3333%;*width:8.3023%}.pure-u-md-1-8,.pure-u-md-3-24{width:12.5%;*width:12.469%}.pure-u-md-1-6,.pure-u-md-4-24{width:16.6667%;*width:16.6357%}.pure-u-md-1-5{width:20%;*width:19.969%}.pure-u-md-5-24{width:20.8333%;*width:20.8023%}.pure-u-md-1-4,.pure-u-md-6-24{width:25%;*width:24.969%}.pure-u-md-7-24{width:29.1667%;*width:29.1357%}.pure-u-md-1-3,.pure-u-md-8-24{width:33.3333%;*width:33.3023%}.pure-u-md-3-8,.pure-u-md-9-24{width:37.5%;*width:37.469%}.pure-u-md-2-5{width:40%;*width:39.969%}.pure-u-md-5-12,.pure-u-md-10-24{width:41.6667%;*width:41.6357%}.pure-u-md-11-24{width:45.8333%;*width:45.8023%}.pure-u-md-1-2,.pure-u-md-12-24{width:50%;*width:49.969%}.pure-u-md-13-24{width:54.1667%;*width:54.1357%}.pure-u-md-7-12,.pure-u-md-14-24{width:58.3333%;*width:58.3023%}.pure-u-md-3-5{width:60%;*width:59.969%}.pure-u-md-5-8,.pure-u-md-15-24{width:62.5%;*width:62.469%}.pure-u-md-2-3,.pure-u-md-16-24{width:66.6667%;*width:66.6357%}.pure-u-md-17-24{width:70.8333%;*width:70.8023%}.pure-u-md-3-4,.pure-u-md-18-24{width:75%;*width:74.969%}.pure-u-md-19-24{width:79.1667%;*width:79.1357%}.pure-u-md-4-5{width:80%;*width:79.969%}.pure-u-md-5-6,.pure-u-md-20-24{width:83.3333%;*width:83.3023%}.pure-u-md-7-8,.pure-u-md-21-24{width:87.5%;*width:87.469%}.pure-u-md-11-12,.pure-u-md-22-24{width:91.6667%;*width:91.6357%}.pure-u-md-23-24{width:95.8333%;*width:95.8023%}.pure-u-md-1,.pure-u-md-1-1,.pure-u-md-5-5,.pure-u-md-24-24{width:100%}}@media screen and (min-width:64em){.pure-u-lg-1,.pure-u-lg-1-1,.pure-u-lg-1-2,.pure-u-lg-1-3,.pure-u-lg-2-3,.pure-u-lg-1-4,.pure-u-lg-3-4,.pure-u-lg-1-5,.pure-u-lg-2-5,.pure-u-lg-3-5,.pure-u-lg-4-5,.pure-u-lg-5-5,.pure-u-lg-1-6,.pure-u-lg-5-6,.pure-u-lg-1-8,.pure-u-lg-3-8,.pure-u-lg-5-8,.pure-u-lg-7-8,.pure-u-lg-1-12,.pure-u-lg-5-12,.pure-u-lg-7-12,.pure-u-lg-11-12,.pure-u-lg-1-24,.pure-u-lg-2-24,.pure-u-lg-3-24,.pure-u-lg-4-24,.pure-u-lg-5-24,.pure-u-lg-6-24,.pure-u-lg-7-24,.pure-u-lg-8-24,.pure-u-lg-9-24,.pure-u-lg-10-24,.pure-u-lg-11-24,.pure-u-lg-12-24,.pure-u-lg-13-24,.pure-u-lg-14-24,.pure-u-lg-15-24,.pure-u-lg-16-24,.pure-u-lg-17-24,.pure-u-lg-18-24,.pure-u-lg-19-24,.pure-u-lg-20-24,.pure-u-lg-21-24,.pure-u-lg-22-24,.pure-u-lg-23-24,.pure-u-lg-24-24{display:inline-block;*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-lg-1-24{width:4.1667%;*width:4.1357%}.pure-u-lg-1-12,.pure-u-lg-2-24{width:8.3333%;*width:8.3023%}.pure-u-lg-1-8,.pure-u-lg-3-24{width:12.5%;*width:12.469%}.pure-u-lg-1-6,.pure-u-lg-4-24{width:16.6667%;*width:16.6357%}.pure-u-lg-1-5{width:20%;*width:19.969%}.pure-u-lg-5-24{width:20.8333%;*width:20.8023%}.pure-u-lg-1-4,.pure-u-lg-6-24{width:25%;*width:24.969%}.pure-u-lg-7-24{width:29.1667%;*width:29.1357%}.pure-u-lg-1-3,.pure-u-lg-8-24{width:33.3333%;*width:33.3023%}.pure-u-lg-3-8,.pure-u-lg-9-24{width:37.5%;*width:37.469%}.pure-u-lg-2-5{width:40%;*width:39.969%}.pure-u-lg-5-12,.pure-u-lg-10-24{width:41.6667%;*width:41.6357%}.pure-u-lg-11-24{width:45.8333%;*width:45.8023%}.pure-u-lg-1-2,.pure-u-lg-12-24{width:50%;*width:49.969%}.pure-u-lg-13-24{width:54.1667%;*width:54.1357%}.pure-u-lg-7-12,.pure-u-lg-14-24{width:58.3333%;*width:58.3023%}.pure-u-lg-3-5{width:60%;*width:59.969%}.pure-u-lg-5-8,.pure-u-lg-15-24{width:62.5%;*width:62.469%}.pure-u-lg-2-3,.pure-u-lg-16-24{width:66.6667%;*width:66.6357%}.pure-u-lg-17-24{width:70.8333%;*width:70.8023%}.pure-u-lg-3-4,.pure-u-lg-18-24{width:75%;*width:74.969%}.pure-u-lg-19-24{width:79.1667%;*width:79.1357%}.pure-u-lg-4-5{width:80%;*width:79.969%}.pure-u-lg-5-6,.pure-u-lg-20-24{width:83.3333%;*width:83.3023%}.pure-u-lg-7-8,.pure-u-lg-21-24{width:87.5%;*width:87.469%}.pure-u-lg-11-12,.pure-u-lg-22-24{width:91.6667%;*width:91.6357%}.pure-u-lg-23-24{width:95.8333%;*width:95.8023%}.pure-u-lg-1,.pure-u-lg-1-1,.pure-u-lg-5-5,.pure-u-lg-24-24{width:100%}}@media screen and (min-width:80em){.pure-u-xl-1,.pure-u-xl-1-1,.pure-u-xl-1-2,.pure-u-xl-1-3,.pure-u-xl-2-3,.pure-u-xl-1-4,.pure-u-xl-3-4,.pure-u-xl-1-5,.pure-u-xl-2-5,.pure-u-xl-3-5,.pure-u-xl-4-5,.pure-u-xl-5-5,.pure-u-xl-1-6,.pure-u-xl-5-6,.pure-u-xl-1-8,.pure-u-xl-3-8,.pure-u-xl-5-8,.pure-u-xl-7-8,.pure-u-xl-1-12,.pure-u-xl-5-12,.pure-u-xl-7-12,.pure-u-xl-11-12,.pure-u-xl-1-24,.pure-u-xl-2-24,.pure-u-xl-3-24,.pure-u-xl-4-24,.pure-u-xl-5-24,.pure-u-xl-6-24,.pure-u-xl-7-24,.pure-u-xl-8-24,.pure-u-xl-9-24,.pure-u-xl-10-24,.pure-u-xl-11-24,.pure-u-xl-12-24,.pure-u-xl-13-24,.pure-u-xl-14-24,.pure-u-xl-15-24,.pure-u-xl-16-24,.pure-u-xl-17-24,.pure-u-xl-18-24,.pure-u-xl-19-24,.pure-u-xl-20-24,.pure-u-xl-21-24,.pure-u-xl-22-24,.pure-u-xl-23-24,.pure-u-xl-24-24{display:inline-block;*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-xl-1-24{width:4.1667%;*width:4.1357%}.pure-u-xl-1-12,.pure-u-xl-2-24{width:8.3333%;*width:8.3023%}.pure-u-xl-1-8,.pure-u-xl-3-24{width:12.5%;*width:12.469%}.pure-u-xl-1-6,.pure-u-xl-4-24{width:16.6667%;*width:16.6357%}.pure-u-xl-1-5{width:20%;*width:19.969%}.pure-u-xl-5-24{width:20.8333%;*width:20.8023%}.pure-u-xl-1-4,.pure-u-xl-6-24{width:25%;*width:24.969%}.pure-u-xl-7-24{width:29.1667%;*width:29.1357%}.pure-u-xl-1-3,.pure-u-xl-8-24{width:33.3333%;*width:33.3023%}.pure-u-xl-3-8,.pure-u-xl-9-24{width:37.5%;*width:37.469%}.pure-u-xl-2-5{width:40%;*width:39.969%}.pure-u-xl-5-12,.pure-u-xl-10-24{width:41.6667%;*width:41.6357%}.pure-u-xl-11-24{width:45.8333%;*width:45.8023%}.pure-u-xl-1-2,.pure-u-xl-12-24{width:50%;*width:49.969%}.pure-u-xl-13-24{width:54.1667%;*width:54.1357%}.pure-u-xl-7-12,.pure-u-xl-14-24{width:58.3333%;*width:58.3023%}.pure-u-xl-3-5{width:60%;*width:59.969%}.pure-u-xl-5-8,.pure-u-xl-15-24{width:62.5%;*width:62.469%}.pure-u-xl-2-3,.pure-u-xl-16-24{width:66.6667%;*width:66.6357%}.pure-u-xl-17-24{width:70.8333%;*width:70.8023%}.pure-u-xl-3-4,.pure-u-xl-18-24{width:75%;*width:74.969%}.pure-u-xl-19-24{width:79.1667%;*width:79.1357%}.pure-u-xl-4-5{width:80%;*width:79.969%}.pure-u-xl-5-6,.pure-u-xl-20-24{width:83.3333%;*width:83.3023%}.pure-u-xl-7-8,.pure-u-xl-21-24{width:87.5%;*width:87.469%}.pure-u-xl-11-12,.pure-u-xl-22-24{width:91.6667%;*width:91.6357%}.pure-u-xl-23-24{width:95.8333%;*width:95.8023%}.pure-u-xl-1,.pure-u-xl-1-1,.pure-u-xl-5-5,.pure-u-xl-24-24{width:100%}} -------------------------------------------------------------------------------- /using-vuejs-in-front-of-drupal-8/css/home.css: -------------------------------------------------------------------------------- 1 | /** 2 | *--------------------------------------------------------- 3 | * Home 4 | *--------------------------------------------------------- 5 | */ 6 | 7 | .home #blurb { 8 | margin-bottom:4rem; 9 | } 10 | div.post.teaser p { 11 | margin-bottom:0; 12 | } -------------------------------------------------------------------------------- /using-vuejs-in-front-of-drupal-8/css/main.css: -------------------------------------------------------------------------------- 1 | @import url('./reset.css'); 2 | @import url('./grids.css'); 3 | @import url('./base.css'); 4 | @import url('./home.css'); 5 | @import url('./posts.css'); 6 | @import url('./menus.css'); 7 | 8 | /** 9 | *--------------------------------------------------------- 10 | * Main 11 | *--------------------------------------------------------- 12 | */ 13 | 14 | #main { 15 | background:#fff; 16 | } 17 | 18 | /** 19 | *--------------------------------------------------------- 20 | * Header 21 | *--------------------------------------------------------- 22 | */ 23 | 24 | header { 25 | background:#fff; 26 | color:rgb(0,0,0,0.2); 27 | } 28 | header .inner { 29 | padding:30px 0 10px; 30 | } 31 | 32 | /** 33 | *--------------------------------------------------------- 34 | * Wrap 35 | *--------------------------------------------------------- 36 | */ 37 | 38 | .wrap { 39 | max-width:75%; 40 | width:100%; 41 | margin:0 auto; 42 | } 43 | 44 | @media screen and (max-width: 35.5em) { 45 | 46 | .wrap { 47 | max-width:85%; 48 | width:100%; 49 | margin:0 auto; 50 | } 51 | 52 | } 53 | 54 | /** 55 | *--------------------------------------------------------- 56 | * Content 57 | *--------------------------------------------------------- 58 | */ 59 | 60 | section#content .inner { 61 | padding:30px 0; 62 | margin: 0 auto; 63 | max-width: 1040px; 64 | } 65 | 66 | /** 67 | *--------------------------------------------------------- 68 | * Footer 69 | *--------------------------------------------------------- 70 | */ 71 | 72 | footer .inner { 73 | padding:40px 0 30px 0; 74 | text-align:center; 75 | } 76 | footer .inner p { 77 | font-weight:300; 78 | color:rgba(255, 255, 255, 0.6); 79 | } -------------------------------------------------------------------------------- /using-vuejs-in-front-of-drupal-8/css/menus.css: -------------------------------------------------------------------------------- 1 | /** 2 | *--------------------------------------------------------- 3 | * Menu 4 | *--------------------------------------------------------- 5 | */ 6 | 7 | nav { 8 | margin-bottom:3rem; 9 | font-size:1.25rem; 10 | text-transform:uppercase; 11 | } 12 | nav .inner { 13 | margin: 0 auto; 14 | max-width: 1040px; 15 | } 16 | nav .wrap { 17 | max-width:75%; 18 | } 19 | nav .wrap ul li { 20 | margin:0 25px 0 0; 21 | } 22 | nav .wrap ul li a { 23 | color:#ccc; 24 | } 25 | nav .wrap ul li a:hover { 26 | color:#454d57; 27 | text-decoration:none; 28 | } -------------------------------------------------------------------------------- /using-vuejs-in-front-of-drupal-8/css/posts.css: -------------------------------------------------------------------------------- 1 | /** 2 | *--------------------------------------------------------- 3 | * Posts 4 | *--------------------------------------------------------- 5 | */ 6 | 7 | div.post.teaser { 8 | border-bottom:1px solid #f2f2f2; 9 | padding-bottom:20px; 10 | margin-bottom:20px; 11 | } 12 | div.post.full p, 13 | div.post.full h2, 14 | div.post.full ul { 15 | margin:0 auto 1.2rem; 16 | width:100%; 17 | max-width:75%; 18 | } 19 | div.post.full h2 { 20 | margin:3rem auto 1.2rem; 21 | } 22 | div.post .date { 23 | margin-bottom:2rem; 24 | border-bottom:1px solid #f2f2f2; 25 | padding-bottom:20px; 26 | } 27 | div.post pre { 28 | max-width:75%; 29 | margin:2rem auto; 30 | width:100%; 31 | } 32 | div.post img { 33 | max-width:85%; 34 | display:block; 35 | margin:2rem auto; 36 | } 37 | 38 | @media screen and (max-width: 35.5em) { 39 | 40 | div.post.full p, 41 | div.post.full h2, 42 | div.post.full ul { 43 | margin:0 auto 1.2rem; 44 | width:100%; 45 | max-width:85%; 46 | } 47 | 48 | div.post pre { 49 | max-width:85%; 50 | margin:2rem auto; 51 | width:100%; 52 | } 53 | 54 | } 55 | 56 | .view { 57 | transition: opacity 0.5s ease; 58 | } 59 | .view.v-enter, 60 | .view.v-leave { 61 | opacity: 0; 62 | } -------------------------------------------------------------------------------- /using-vuejs-in-front-of-drupal-8/css/reset.css: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v2.0 | 20110126 3 | License: none (public domain) 4 | */ 5 | 6 | html, body, div, span, applet, object, iframe, 7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 8 | a, abbr, acronym, address, big, cite, code, 9 | del, dfn, em, img, ins, kbd, q, s, samp, 10 | small, strike, strong, sub, sup, tt, var, 11 | b, u, i, center, 12 | dl, dt, dd, ol, ul, li, 13 | fieldset, form, label, legend, 14 | table, caption, tbody, tfoot, thead, tr, th, td, 15 | article, aside, canvas, details, embed, 16 | figure, figcaption, footer, header, hgroup, 17 | menu, nav, output, ruby, section, summary, 18 | time, mark, audio, video { 19 | margin: 0; 20 | padding: 0; 21 | border: 0; 22 | font-size: 100%; 23 | font: inherit; 24 | vertical-align: baseline; 25 | } 26 | /* HTML5 display-role reset for older browsers */ 27 | article, aside, details, figcaption, figure, 28 | footer, header, hgroup, menu, nav, section { 29 | display: block; 30 | } 31 | body { 32 | line-height: 1; 33 | } 34 | ol, ul { 35 | list-style: none; 36 | } 37 | blockquote, q { 38 | quotes: none; 39 | } 40 | blockquote:before, blockquote:after, 41 | q:before, q:after { 42 | content: ''; 43 | content: none; 44 | } 45 | table { 46 | border-collapse: collapse; 47 | border-spacing: 0; 48 | } -------------------------------------------------------------------------------- /using-vuejs-in-front-of-drupal-8/drupal/modules/api/api.info.yml: -------------------------------------------------------------------------------- 1 | name: API 2 | type: module 3 | description: 'Exposes custom REST api.' 4 | package: Web services 5 | version: 1.0 6 | core: 8.x 7 | -------------------------------------------------------------------------------- /using-vuejs-in-front-of-drupal-8/drupal/modules/api/api.module: -------------------------------------------------------------------------------- 1 | getArticle($uuid); 34 | return new ResourceResponse($this->transform($entity)); 35 | } else { 36 | return new ResourceResponse([ 37 | 'http_code' => 400, 38 | 'error' => 100, 39 | 'message' => 'The UUID supplied is invalid.' 40 | ], 400); 41 | } 42 | } 43 | 44 | /** 45 | * Get article by UUID. 46 | * 47 | * @param $uuid 48 | * 49 | * @return array 50 | */ 51 | public function getArticle($uuid) { 52 | $entity = \Drupal::entityManager()->getStorage('node')->loadByProperties([ 53 | 'uuid' => $uuid, 54 | 'type' => 'article' 55 | ]); 56 | 57 | return reset($entity); 58 | } 59 | 60 | /** 61 | * @param $entity 62 | * 63 | * @return array 64 | */ 65 | private function transform($entity) { 66 | return [ 67 | 'id' => (int) $entity->nid[0]->value, 68 | 'title' => $entity->title[0]->value, 69 | 'body' => $entity->body[0]->value, 70 | 'links' => [ 71 | [ 72 | 'rel' => 'self', 73 | 'uri' => '/api/v1.0/articles/'.$entity->uuid[0]->value 74 | ], 75 | [ 76 | 'rel' => 'article.comments', 77 | 'uri' => '/api/v1.0/articles/'.$entity->uuid[0]->value.'/comments' 78 | ] 79 | ] 80 | ]; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /using-vuejs-in-front-of-drupal-8/drupal/modules/api/src/Plugin/Rest/Resource/v1_0/BaseBundleResource.php: -------------------------------------------------------------------------------- 1 | getParameter('serializer.formats'), 42 | $container->get('logger.factory')->get('rest'), 43 | $container->get('entity.manager'), 44 | $container->get('current_user') 45 | ); 46 | } 47 | 48 | /** 49 | * Constructs a Drupal\rest\Plugin\ResourceBase object. 50 | * 51 | * @param array $configuration 52 | * A configuration array containing information about the plugin instance. 53 | * @param string $plugin_id 54 | * The plugin_id for the plugin instance. 55 | * @param mixed $plugin_definition 56 | * The plugin implementation definition. 57 | * @param array $serializer_formats 58 | * The available serialization formats. 59 | * @param \Psr\Log\LoggerInterface $logger 60 | * A logger instance. 61 | * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager 62 | * Entity manager instance. 63 | * @param \Drupal\Core\Session\AccountProxyInterface $current_user 64 | * Current user object. 65 | */ 66 | public function __construct( 67 | array $configuration, 68 | $plugin_id, 69 | $plugin_definition, 70 | array $serializer_formats, 71 | LoggerInterface $logger, 72 | EntityManagerInterface $entity_manager, 73 | AccountProxyInterface $current_user) { 74 | parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger); 75 | 76 | $this->entityManager = $entity_manager; 77 | $this->currentUser = $current_user; 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /using-vuejs-in-front-of-drupal-8/drupal/modules/api/src/Plugin/Rest/Resource/v2_0/ArticleBundleResource.php: -------------------------------------------------------------------------------- 1 | getArticle($uuid); 34 | return new ResourceResponse($this->transform($entity)); 35 | } else { 36 | return new ResourceResponse([ 37 | 'http_code' => 400, 38 | 'error' => 100, 39 | 'message' => 'The UUID supplied is invalid.' 40 | ], 400); 41 | } 42 | } 43 | 44 | /** 45 | * Get article by UUID. 46 | * 47 | * @param $uuid 48 | * 49 | * @return array 50 | */ 51 | public function getArticle($uuid) { 52 | $entity = \Drupal::entityManager()->getStorage('node')->loadByProperties([ 53 | 'uuid' => $uuid, 54 | 'type' => 'article' 55 | ]); 56 | 57 | return reset($entity); 58 | } 59 | 60 | /** 61 | * @param $entity 62 | * 63 | * @return array 64 | */ 65 | private function transform($entity) { 66 | return [ 67 | 'title' => $entity->title[0]->value, 68 | 'body' => $entity->body[0]->value, 69 | 'links' => [ 70 | [ 71 | 'rel' => 'self', 72 | 'uri' => '/api/v2.0/articles/'.$entity->uuid[0]->value 73 | ] 74 | ] 75 | ]; 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /using-vuejs-in-front-of-drupal-8/drupal/modules/api/src/Plugin/Rest/Resource/v2_0/BaseBundleResource.php: -------------------------------------------------------------------------------- 1 | getParameter('serializer.formats'), 42 | $container->get('logger.factory')->get('rest'), 43 | $container->get('entity.manager'), 44 | $container->get('current_user') 45 | ); 46 | } 47 | 48 | /** 49 | * Constructs a Drupal\rest\Plugin\ResourceBase object. 50 | * 51 | * @param array $configuration 52 | * A configuration array containing information about the plugin instance. 53 | * @param string $plugin_id 54 | * The plugin_id for the plugin instance. 55 | * @param mixed $plugin_definition 56 | * The plugin implementation definition. 57 | * @param array $serializer_formats 58 | * The available serialization formats. 59 | * @param \Psr\Log\LoggerInterface $logger 60 | * A logger instance. 61 | * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager 62 | * Entity manager instance. 63 | * @param \Drupal\Core\Session\AccountProxyInterface $current_user 64 | * Current user object. 65 | */ 66 | public function __construct( 67 | array $configuration, 68 | $plugin_id, 69 | $plugin_definition, 70 | array $serializer_formats, 71 | LoggerInterface $logger, 72 | EntityManagerInterface $entity_manager, 73 | AccountProxyInterface $current_user) { 74 | parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger); 75 | 76 | $this->entityManager = $entity_manager; 77 | $this->currentUser = $current_user; 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /using-vuejs-in-front-of-drupal-8/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Using VueJS in front of Drupal 8 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 |
22 | 29 | 30 |
31 | 32 |
33 |
34 |
35 |
36 |
37 | 38 |
39 | 40 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /using-vuejs-in-front-of-drupal-8/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "site", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "./src/app.js", 6 | "scripts": { 7 | "build": "browserify -v -t vueify -e ./src/app.js -o build/build.js", 8 | "watch": "watchify -v -t vueify -e ./src/app.js -o build/build.js" 9 | }, 10 | "author": "Bri Ward (http://briward.com)", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "insert-css": "^0.2.0", 14 | "vueify": "^1.1.5", 15 | "watchify": "^3.3.1" 16 | }, 17 | "dependencies": { 18 | "director": "^1.2.8", 19 | "vue": "^0.12.9", 20 | "vue-resource": "^0.1.11" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /using-vuejs-in-front-of-drupal-8/src/app.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Boot up the Vue instance and wire up the router. 3 | */ 4 | var Vue = require('vue') 5 | Vue.use(require('vue-resource')) 6 | var Router = require('director').Router 7 | var app = new Vue(require('./app.vue')) 8 | var router = new Router() 9 | 10 | /** 11 | * Router. 12 | */ 13 | router.on('/articles/:uuid', function (uuid) { 14 | app.view = 'article-view' 15 | app.params.uuid = uuid 16 | }) 17 | 18 | router.init('/') 19 | -------------------------------------------------------------------------------- /using-vuejs-in-front-of-drupal-8/src/app.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 24 | -------------------------------------------------------------------------------- /using-vuejs-in-front-of-drupal-8/src/views/article-view.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 36 | --------------------------------------------------------------------------------