├── .gitignore ├── 404.md ├── CNAME ├── Gemfile ├── Gemfile.lock ├── _config.yml ├── _data └── navbar.yml ├── _includes ├── navbar.html └── toc.html ├── _layouts └── default.html ├── about.md ├── assets └── style.css ├── case-study ├── fragment-cache.md ├── laps.md ├── scbframework.md ├── tlc-transients.md └── wordpress-seo.md ├── favicon.ico ├── index.md ├── recipe ├── core-package.md ├── paths-control.md └── site-stack.md ├── resources.md ├── serve.cmd └── slides.md /.gitignore: -------------------------------------------------------------------------------- 1 | \.idea 2 | _site 3 | .sass-cache 4 | .jekyll-metadata -------------------------------------------------------------------------------- /404.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: '404' 3 | subtitle: error 4 | permalink: /404.html 5 | --- 6 | 7 | Something is not right here... 8 | 9 | Make Everything Ok -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | composer.rarst.net -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | # Hello! This is where you manage which Jekyll version is used to run. 4 | # When you want to use a different version, change it below, save the 5 | # file and run `bundle install`. Run Jekyll with `bundle exec`, like so: 6 | # 7 | # bundle exec jekyll serve 8 | # 9 | # This will help ensure the proper Jekyll version is running. 10 | # Happy Jekylling! 11 | # gem "jekyll", "~> 3.6.2" 12 | 13 | # This is the default theme for new Jekyll sites. You may change this to anything you like. 14 | # gem "minima", "~> 2.0" 15 | 16 | # If you want to use GitHub Pages, remove the "gem "jekyll"" above and 17 | # uncomment the line below. To upgrade, run `bundle update github-pages`. 18 | gem "github-pages", group: :jekyll_plugins 19 | 20 | # If you have any plugins, put them here! 21 | group :jekyll_plugins do 22 | # gem "jekyll-feed", "~> 0.6" 23 | end 24 | 25 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem 26 | gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] 27 | 28 | gem 'wdm', '>= 0.1.0' if Gem.win_platform? -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | activesupport (4.2.9) 5 | i18n (~> 0.7) 6 | minitest (~> 5.1) 7 | thread_safe (~> 0.3, >= 0.3.4) 8 | tzinfo (~> 1.1) 9 | addressable (2.5.2) 10 | public_suffix (>= 2.0.2, < 4.0) 11 | coffee-script (2.4.1) 12 | coffee-script-source 13 | execjs 14 | coffee-script-source (1.11.1) 15 | colorator (1.1.0) 16 | commonmarker (0.17.7.1) 17 | ruby-enum (~> 0.5) 18 | concurrent-ruby (1.0.5) 19 | ethon (0.11.0) 20 | ffi (>= 1.3.0) 21 | execjs (2.7.0) 22 | faraday (0.13.1) 23 | multipart-post (>= 1.2, < 3) 24 | ffi (1.9.18-x64-mingw32) 25 | forwardable-extended (2.6.0) 26 | gemoji (3.0.0) 27 | github-pages (172) 28 | activesupport (= 4.2.9) 29 | github-pages-health-check (= 1.3.5) 30 | jekyll (= 3.6.2) 31 | jekyll-avatar (= 0.5.0) 32 | jekyll-coffeescript (= 1.0.2) 33 | jekyll-commonmark-ghpages (= 0.1.3) 34 | jekyll-default-layout (= 0.1.4) 35 | jekyll-feed (= 0.9.2) 36 | jekyll-gist (= 1.4.1) 37 | jekyll-github-metadata (= 2.9.3) 38 | jekyll-mentions (= 1.2.0) 39 | jekyll-optional-front-matter (= 0.3.0) 40 | jekyll-paginate (= 1.1.0) 41 | jekyll-readme-index (= 0.2.0) 42 | jekyll-redirect-from (= 0.12.1) 43 | jekyll-relative-links (= 0.5.2) 44 | jekyll-remote-theme (= 0.2.3) 45 | jekyll-sass-converter (= 1.5.0) 46 | jekyll-seo-tag (= 2.3.0) 47 | jekyll-sitemap (= 1.1.1) 48 | jekyll-swiss (= 0.4.0) 49 | jekyll-theme-architect (= 0.1.0) 50 | jekyll-theme-cayman (= 0.1.0) 51 | jekyll-theme-dinky (= 0.1.0) 52 | jekyll-theme-hacker (= 0.1.0) 53 | jekyll-theme-leap-day (= 0.1.0) 54 | jekyll-theme-merlot (= 0.1.0) 55 | jekyll-theme-midnight (= 0.1.0) 56 | jekyll-theme-minimal (= 0.1.0) 57 | jekyll-theme-modernist (= 0.1.0) 58 | jekyll-theme-primer (= 0.5.2) 59 | jekyll-theme-slate (= 0.1.0) 60 | jekyll-theme-tactile (= 0.1.0) 61 | jekyll-theme-time-machine (= 0.1.0) 62 | jekyll-titles-from-headings (= 0.5.0) 63 | jemoji (= 0.8.1) 64 | kramdown (= 1.14.0) 65 | liquid (= 4.0.0) 66 | listen (= 3.0.6) 67 | mercenary (~> 0.3) 68 | minima (= 2.1.1) 69 | rouge (= 2.2.1) 70 | terminal-table (~> 1.4) 71 | github-pages-health-check (1.3.5) 72 | addressable (~> 2.3) 73 | net-dns (~> 0.8) 74 | octokit (~> 4.0) 75 | public_suffix (~> 2.0) 76 | typhoeus (~> 0.7) 77 | html-pipeline (2.7.1) 78 | activesupport (>= 2) 79 | nokogiri (>= 1.4) 80 | i18n (0.9.1) 81 | concurrent-ruby (~> 1.0) 82 | jekyll (3.6.2) 83 | addressable (~> 2.4) 84 | colorator (~> 1.0) 85 | jekyll-sass-converter (~> 1.0) 86 | jekyll-watch (~> 1.1) 87 | kramdown (~> 1.14) 88 | liquid (~> 4.0) 89 | mercenary (~> 0.3.3) 90 | pathutil (~> 0.9) 91 | rouge (>= 1.7, < 3) 92 | safe_yaml (~> 1.0) 93 | jekyll-avatar (0.5.0) 94 | jekyll (~> 3.0) 95 | jekyll-coffeescript (1.0.2) 96 | coffee-script (~> 2.2) 97 | coffee-script-source (~> 1.11.1) 98 | jekyll-commonmark (1.1.0) 99 | commonmarker (~> 0.14) 100 | jekyll (>= 3.0, < 4.0) 101 | jekyll-commonmark-ghpages (0.1.3) 102 | commonmarker (~> 0.17.6) 103 | jekyll-commonmark (~> 1) 104 | rouge (~> 2) 105 | jekyll-default-layout (0.1.4) 106 | jekyll (~> 3.0) 107 | jekyll-feed (0.9.2) 108 | jekyll (~> 3.3) 109 | jekyll-gist (1.4.1) 110 | octokit (~> 4.2) 111 | jekyll-github-metadata (2.9.3) 112 | jekyll (~> 3.1) 113 | octokit (~> 4.0, != 4.4.0) 114 | jekyll-mentions (1.2.0) 115 | activesupport (~> 4.0) 116 | html-pipeline (~> 2.3) 117 | jekyll (~> 3.0) 118 | jekyll-optional-front-matter (0.3.0) 119 | jekyll (~> 3.0) 120 | jekyll-paginate (1.1.0) 121 | jekyll-readme-index (0.2.0) 122 | jekyll (~> 3.0) 123 | jekyll-redirect-from (0.12.1) 124 | jekyll (~> 3.3) 125 | jekyll-relative-links (0.5.2) 126 | jekyll (~> 3.3) 127 | jekyll-remote-theme (0.2.3) 128 | jekyll (~> 3.5) 129 | rubyzip (>= 1.2.1, < 3.0) 130 | typhoeus (>= 0.7, < 2.0) 131 | jekyll-sass-converter (1.5.0) 132 | sass (~> 3.4) 133 | jekyll-seo-tag (2.3.0) 134 | jekyll (~> 3.3) 135 | jekyll-sitemap (1.1.1) 136 | jekyll (~> 3.3) 137 | jekyll-swiss (0.4.0) 138 | jekyll-theme-architect (0.1.0) 139 | jekyll (~> 3.5) 140 | jekyll-seo-tag (~> 2.0) 141 | jekyll-theme-cayman (0.1.0) 142 | jekyll (~> 3.5) 143 | jekyll-seo-tag (~> 2.0) 144 | jekyll-theme-dinky (0.1.0) 145 | jekyll (~> 3.5) 146 | jekyll-seo-tag (~> 2.0) 147 | jekyll-theme-hacker (0.1.0) 148 | jekyll (~> 3.5) 149 | jekyll-seo-tag (~> 2.0) 150 | jekyll-theme-leap-day (0.1.0) 151 | jekyll (~> 3.5) 152 | jekyll-seo-tag (~> 2.0) 153 | jekyll-theme-merlot (0.1.0) 154 | jekyll (~> 3.5) 155 | jekyll-seo-tag (~> 2.0) 156 | jekyll-theme-midnight (0.1.0) 157 | jekyll (~> 3.5) 158 | jekyll-seo-tag (~> 2.0) 159 | jekyll-theme-minimal (0.1.0) 160 | jekyll (~> 3.5) 161 | jekyll-seo-tag (~> 2.0) 162 | jekyll-theme-modernist (0.1.0) 163 | jekyll (~> 3.5) 164 | jekyll-seo-tag (~> 2.0) 165 | jekyll-theme-primer (0.5.2) 166 | jekyll (~> 3.5) 167 | jekyll-github-metadata (~> 2.9) 168 | jekyll-seo-tag (~> 2.2) 169 | jekyll-theme-slate (0.1.0) 170 | jekyll (~> 3.5) 171 | jekyll-seo-tag (~> 2.0) 172 | jekyll-theme-tactile (0.1.0) 173 | jekyll (~> 3.5) 174 | jekyll-seo-tag (~> 2.0) 175 | jekyll-theme-time-machine (0.1.0) 176 | jekyll (~> 3.5) 177 | jekyll-seo-tag (~> 2.0) 178 | jekyll-titles-from-headings (0.5.0) 179 | jekyll (~> 3.3) 180 | jekyll-watch (1.5.1) 181 | listen (~> 3.0) 182 | jemoji (0.8.1) 183 | activesupport (~> 4.0, >= 4.2.9) 184 | gemoji (~> 3.0) 185 | html-pipeline (~> 2.2) 186 | jekyll (>= 3.0) 187 | kramdown (1.14.0) 188 | liquid (4.0.0) 189 | listen (3.0.6) 190 | rb-fsevent (>= 0.9.3) 191 | rb-inotify (>= 0.9.7) 192 | mercenary (0.3.6) 193 | mini_portile2 (2.3.0) 194 | minima (2.1.1) 195 | jekyll (~> 3.3) 196 | minitest (5.11.1) 197 | multipart-post (2.0.0) 198 | net-dns (0.8.0) 199 | nokogiri (1.8.1-x64-mingw32) 200 | mini_portile2 (~> 2.3.0) 201 | octokit (4.8.0) 202 | sawyer (~> 0.8.0, >= 0.5.3) 203 | pathutil (0.16.1) 204 | forwardable-extended (~> 2.6) 205 | public_suffix (2.0.5) 206 | rb-fsevent (0.10.2) 207 | rb-inotify (0.9.10) 208 | ffi (>= 0.5.0, < 2) 209 | rouge (2.2.1) 210 | ruby-enum (0.7.1) 211 | i18n 212 | rubyzip (1.2.1) 213 | safe_yaml (1.0.4) 214 | sass (3.5.5) 215 | sass-listen (~> 4.0.0) 216 | sass-listen (4.0.0) 217 | rb-fsevent (~> 0.9, >= 0.9.4) 218 | rb-inotify (~> 0.9, >= 0.9.7) 219 | sawyer (0.8.1) 220 | addressable (>= 2.3.5, < 2.6) 221 | faraday (~> 0.8, < 1.0) 222 | terminal-table (1.8.0) 223 | unicode-display_width (~> 1.1, >= 1.1.1) 224 | thread_safe (0.3.6) 225 | typhoeus (0.8.0) 226 | ethon (>= 0.8.0) 227 | tzinfo (1.2.4) 228 | thread_safe (~> 0.1) 229 | tzinfo-data (1.2017.3) 230 | tzinfo (>= 1.0.0) 231 | unicode-display_width (1.3.0) 232 | wdm (0.1.1) 233 | 234 | PLATFORMS 235 | x64-mingw32 236 | 237 | DEPENDENCIES 238 | github-pages 239 | tzinfo-data 240 | wdm (>= 0.1.0) 241 | 242 | BUNDLED WITH 243 | 1.16.1 244 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | # Welcome to Jekyll! 2 | # 3 | # This config file is meant for settings that affect your whole blog, values 4 | # which you are expected to set up once and rarely edit after that. If you find 5 | # yourself editing this file very often, consider using Jekyll's data files 6 | # feature for the data you need to update frequently. 7 | # 8 | # For technical reasons, this file is *NOT* reloaded automatically when you use 9 | # 'bundle exec jekyll serve'. If you change this file, please restart the server process. 10 | 11 | # Site settings 12 | # These are used to personalize your new site. If you look in the HTML files, 13 | # you will see them accessed via {{ site.title }}, {{ site.email }}, and so on. 14 | # You can create any custom variable you would like, and they will be accessible 15 | # in the templates via {{ site.myvariable }}. 16 | title: Composer in WordPress 17 | description: >- # this means to ignore newlines until "baseurl:" 18 | Your Guide to Composer in WordPress 19 | baseurl: "" # the subpath of your site, e.g. /blog 20 | url: "https://composer.rarst.net" # the base hostname & protocol for your site, e.g. http://example.com 21 | permalink: pretty 22 | 23 | # Build settings 24 | markdown: kramdown 25 | # theme: minima 26 | plugins: 27 | - jekyll-sitemap 28 | 29 | # Exclude from processing. 30 | # The following items will not be processed, by default. Create a custom list 31 | # to override the default setting. 32 | exclude: 33 | - Gemfile 34 | - Gemfile.lock 35 | - node_modules 36 | - vendor/bundle/ 37 | - vendor/cache/ 38 | - vendor/gems/ 39 | - vendor/ruby/ 40 | - .idea 41 | - serve.cmd -------------------------------------------------------------------------------- /_data/navbar.yml: -------------------------------------------------------------------------------- 1 | menu: 2 | - anchor: Recipes… 3 | url: /#recipes 4 | dropdown: 5 | - anchor: Core Package 6 | url: /recipe/core-package/ 7 | 8 | - anchor: Paths Control 9 | url: /recipe/paths-control/ 10 | 11 | - anchor: Site Stack 12 | url: /recipe/site-stack/ 13 | 14 | - anchor: Case Studies… 15 | url: /#case-studies 16 | dropdown: 17 | - header: Updated 18 | 19 | - anchor: WordPress SEO 20 | url: /case-study/wordpress-seo/ 21 | 22 | - anchor: TLC Transients 23 | url: /case-study/tlc-transients/ 24 | 25 | - anchor: scbFramework 26 | url: /case-study/scbframework/ 27 | 28 | - header: Developed 29 | 30 | - anchor: Laps 31 | url: /case-study/laps/ 32 | 33 | - anchor: Fragment Cache 34 | url: /case-study/fragment-cache/ 35 | 36 | - anchor: Resources 37 | url: /resources/ 38 | 39 | - anchor: About 40 | url: /about/ -------------------------------------------------------------------------------- /_includes/navbar.html: -------------------------------------------------------------------------------- 1 | 39 | -------------------------------------------------------------------------------- /_includes/toc.html: -------------------------------------------------------------------------------- 1 | {% capture tocWorkspace %} 2 | {% comment %} 3 | Version 1.0.2 4 | 5 | "...like all things liquid - where there's a will, and ~36 hours to spare, there's usually a/some way" ~jaybe 6 | 7 | Usage: 8 | {% include toc.html html=content sanitize=true class="inline_toc" id="my_toc" h_min=2 h_max=3 %} 9 | 10 | Parameters: 11 | * html (string) - the HTML of compiled markdown generated by kramdown in Jekyll 12 | 13 | Optional Parameters: 14 | * sanitize (bool) : false - when set to true, the headers will be stripped of any HTML in the TOC 15 | * class (string) : '' - a CSS class assigned to the TOC 16 | * id (string) : '' - an ID to assigned to the TOC 17 | * h_min (int) : 1 - the minimum TOC header level to use; any header lower than this value will be ignored 18 | * h_max (int) : 6 - the maximum TOC header level to use; any header greater than this value will be ignored 19 | 20 | Output: 21 | An unordered list representing the table of contents of a markdown block. This snippet will only generate the table of contents and will NOT output the markdown given to it 22 | {% endcomment %} 23 | 24 | {% capture my_toc %}{% endcapture %} 25 | {% assign minHeader = include.h_min | default: 1 %} 26 | {% assign maxHeader = include.h_max | default: 6 %} 27 | {% assign nodes = include.html | split: ' maxHeader %} 38 | {% continue %} 39 | {% endif %} 40 | 41 | {% if firstHeader %} 42 | {% assign firstHeader = false %} 43 | {% assign minHeader = headerLevel %} 44 | {% endif %} 45 | 46 | {% assign indentAmount = headerLevel | minus: minHeader | add: 1 %} 47 | {% assign _workspace = node | split: '' | first }}>{% endcapture %} 54 | {% assign header = _workspace[0] | replace: _hAttrToStrip, '' %} 55 | 56 | {% assign space = '' %} 57 | {% for i in (1..indentAmount) %} 58 | {% assign space = space | prepend: ' ' %} 59 | {% endfor %} 60 | 61 | {% capture my_toc %}{{ my_toc }} 62 | {{ space }}- [{% if include.sanitize %}{{ header | strip_html }}{% else %}{{ header }}{% endif %}](#{{ html_id }}){% endcapture %} 63 | 64 | {% endfor %} 65 | 66 | {% if include.class %} 67 | {% capture my_toc %}{:.{{ include.class }}} 68 | {{ my_toc | lstrip }}{% endcapture %} 69 | {% endif %} 70 | 71 | {% if include.id %} 72 | {% capture my_toc %}{: #{{ include.id }}} 73 | {{ my_toc | lstrip }}{% endcapture %} 74 | {% endif %} 75 | {% endcapture %}{% assign tocWorkspace = '' %}{{ my_toc | markdownify | strip }} -------------------------------------------------------------------------------- /_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {% if page.title and page.frontpage != true %}{{ page.title | escape }} | {% endif %}{{ site.title | escape }} 6 | {%- if page.excerpt %} 7 | 8 | {% endif -%} 9 | 10 | 11 | 12 | 13 | 14 | 15 | {% include navbar.html %} 16 | 17 |
18 |
19 |
20 | 23 |
24 |
25 |
26 |
27 | {% include toc.html html=content id='toc' class='nav.nav-pills.nav-stacked' h_max=2 %} 28 |
29 |
30 | {{ content }} 31 |
32 |
33 | 34 | 39 |
40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /about.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: About 3 | excerpt: Info about the “Composer in WordPress site” 4 | --- 5 | 6 | This site had been created by [Andrey “Rarst” Savchenko](https://www.rarst.net), who became Composer evangelist in WordPress circles after he got bitten by wild Composer in early 2013 (unconfirmed rumor). 7 | 8 | He has been asked “but where can I read about all of that!?” few too many times and now this is it. 9 | 10 | ## Contact 11 | 12 | This site’s goal is to provide and point to any information you could possibly need about using Composer with WordPress projects. 13 | 14 | So don’t hesitate to contact with questions or suggestions! 15 | 16 | - pull request to [GitHub/Rarst/composer-in-wp](https://github.com/Rarst/composer-in-wp) or [open issue](https://github.com/Rarst/composer-in-wp/issues) 17 | - tweet or DM [@Rarst](https://twitter.com/Rarst) 18 | 19 | ## Internals 20 | 21 | - [GitHub Pages](https://pages.github.com/) 22 | - [Jekyll Pure Liquid Table of Contents](https://github.com/allejo/jekyll-toc) 23 | - [Twitter Bootstrap](http://getbootstrap.com/) with [Readable theme](https://bootswatch.com/3/readable/) 24 | - scripts 25 | - [jQuery](http://jquery.com/) 26 | - CDNs 27 | - [Google Hosted Libraries](https://developers.google.com/speed/libraries/) 28 | - [BootstrapCDN](https://www.bootstrapcdn.com/) 29 | 30 | ## Changelog 31 | - **2018-11** 32 | - fixed broken links 33 | - updated links to secure versions 34 | - **2018-02** 35 | - updates site stack recipe 36 | - **2018-01** 37 | - moved to GitHub Pages 38 | - **2017-12** 39 | - updated resources page (added Private Packagist, Release Belt) 40 | - **2015-03** 41 | - updated scripts and styles 42 | - added WordPress SEO case study 43 | - **2014-07** 44 | - updated scripts and styles 45 | - updated resources 46 | - refreshed case studies 47 | - **2013-11** 48 | - updated scripts and styles 49 | - removed mentions of imploded trac ticket 50 | - added `johnpbloch/wordpress` info 51 | - **2013-08** 52 | - updated repos and guide to using core installer 53 | - **2013-07** 54 | - it’s alive! -------------------------------------------------------------------------------- /assets/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-size: 20px; 3 | } 4 | 5 | @media (min-width:992px) { 6 | 7 | #toc-sticky { 8 | position: -webkit-sticky; 9 | position: -moz-sticky; 10 | position: sticky; 11 | top: 15px; 12 | } 13 | } 14 | 15 | #toc { 16 | margin-bottom: 30px; 17 | padding: 0; 18 | width: 208px; 19 | } 20 | 21 | #toc.affix { 22 | top: 40px; 23 | } 24 | 25 | #toc.affix-bottom { 26 | position: absolute; 27 | top: auto; 28 | bottom: 270px; 29 | } 30 | 31 | pre { 32 | background-color: #fdf6e3; 33 | } 34 | 35 | code { 36 | color: #657b83; 37 | background-color: #fdf6e3; 38 | } 39 | 40 | .navbar-static-top { 41 | border-bottom: none; 42 | } 43 | 44 | .footer { 45 | margin-bottom: 10px; 46 | padding-top: 10px; 47 | border-top: solid 1px #eee; 48 | text-align: center; 49 | } 50 | 51 | @media (min-width: 1200px) { 52 | 53 | #toc { 54 | width: 258px; 55 | } 56 | } 57 | 58 | @media (max-width: 980px) { 59 | 60 | #toc { 61 | top: 0; 62 | width: 218px; 63 | margin-right: 0; 64 | } 65 | } 66 | 67 | @media (min-width: 768px) and (max-width: 979px) { 68 | 69 | #toc { 70 | width: 166px; 71 | } 72 | #toc.affix { 73 | top: 0; 74 | } 75 | } 76 | 77 | @media (max-width: 979px) { 78 | #toc { 79 | width: auto; 80 | margin-bottom: 20px; 81 | } 82 | #toc.affix { 83 | position: static; 84 | width: auto; 85 | top: 0; 86 | } 87 | } 88 | 89 | /* rougify style base16.solarized > solarized.css*/ 90 | 91 | .highlight table td { padding: 5px; } 92 | .highlight table pre { margin: 0; } 93 | .highlight, .highlight .w { 94 | color: #586e75; 95 | } 96 | .highlight .err { 97 | color: #002b36; 98 | background-color: #dc322f; 99 | } 100 | .highlight .c, .highlight .cd, .highlight .cm, .highlight .c1, .highlight .cs { 101 | color: #657b83; 102 | } 103 | .highlight .cp { 104 | color: #b58900; 105 | } 106 | .highlight .nt { 107 | color: #b58900; 108 | } 109 | .highlight .o, .highlight .ow { 110 | color: #93a1a1; 111 | } 112 | .highlight .p, .highlight .pi { 113 | color: #93a1a1; 114 | } 115 | .highlight .gi { 116 | color: #859900; 117 | } 118 | .highlight .gd { 119 | color: #dc322f; 120 | } 121 | .highlight .gh { 122 | color: #268bd2; 123 | background-color: #002b36; 124 | font-weight: bold; 125 | } 126 | .highlight .k, .highlight .kn, .highlight .kp, .highlight .kr, .highlight .kv { 127 | color: #6c71c4; 128 | } 129 | .highlight .kc { 130 | color: #cb4b16; 131 | } 132 | .highlight .kt { 133 | color: #cb4b16; 134 | } 135 | .highlight .kd { 136 | color: #cb4b16; 137 | } 138 | .highlight .s, .highlight .sb, .highlight .sc, .highlight .sd, .highlight .s2, .highlight .sh, .highlight .sx, .highlight .s1 { 139 | color: #859900; 140 | } 141 | .highlight .sr { 142 | color: #2aa198; 143 | } 144 | .highlight .si { 145 | color: #d33682; 146 | } 147 | .highlight .se { 148 | color: #d33682; 149 | } 150 | .highlight .nn { 151 | color: #b58900; 152 | } 153 | .highlight .nc { 154 | color: #b58900; 155 | } 156 | .highlight .no { 157 | color: #b58900; 158 | } 159 | .highlight .na { 160 | color: #268bd2; 161 | } 162 | .highlight .m, .highlight .mf, .highlight .mh, .highlight .mi, .highlight .il, .highlight .mo, .highlight .mb, .highlight .mx { 163 | color: #859900; 164 | } 165 | .highlight .ss { 166 | color: #859900; 167 | } 168 | -------------------------------------------------------------------------------- /case-study/fragment-cache.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Fragment Cache 3 | subtitle: case study 4 | --- 5 | 6 | - development repository : [GitHub](https://github.com/Rarst/fragment-cache) 7 | - Composer repository : [Packagist](https://packagist.org/packages/rarst/fragment-cache) 8 | - versioning : semantic 9 | - dependencies : [Pimple](https://pimple.symfony.com/), [TLC Transients](/case-study/tlc-transients) 10 | - suggests : [Update Blocker](https://github.com/Rarst/update-blocker) 11 | 12 | ## Development 13 | 14 | Fragment Cache is caching plugin for WordPress. It was developed exclusively as Composer package. 15 | 16 | `classmap` autoload type is used for classes, since files adhere to WordPress naming convention and need to be handled by static scan on install. 17 | 18 | Pimple and TLC Transients libraries are required as Composer dependencies. Main plugin’s class extends Pimple and acts as dependency injection container for handler classes of different cache types. TLC Transients functionality is used for asynchronous cache updates. 19 | 20 | [Update Blocker](https://github.com/Rarst/update-blocker) plugin is suggested to prevent invalid update of Fragment Cache from official WordPress repository. 21 | 22 | `composer/installers` package and `wordpress-plugin` type are declared for [path customization](/recipe/paths-control) when plugin is installed as part of [whole site stack](/recipe/site-stack). 23 | 24 | ## composer.json 25 | 26 | ```json 27 | { 28 | "name" : "rarst/fragment-cache", 29 | "description" : "WordPress plugin for partial and async caching of heavy front-end elements.", 30 | "keywords" : ["wordpress", "cache", "performance"], 31 | "type" : "wordpress-plugin", 32 | "homepage" : "https://github.com/Rarst/fragment-cache", 33 | "license" : "GPL-2.0+", 34 | "authors" : [ 35 | { 36 | "name" : "Andrey Savchenko", 37 | "homepage": "https://www.rarst.net/" 38 | } 39 | ], 40 | "support" : { 41 | "issues": "https://github.com/Rarst/fragment-cache/issues" 42 | }, 43 | "require" : { 44 | "composer/installers" : "~1.0", 45 | "markjaquith/wp-tlc-transients": "~1.0", 46 | "php" : ">=5.3", 47 | "pimple/pimple" : "~2.0" 48 | }, 49 | "suggest": { 50 | "rarst/update-blocker": "Prevents invalid updates from official repositories" 51 | }, 52 | "autoload" : { 53 | "classmap": ["php/"] 54 | } 55 | } 56 | ``` 57 | 58 | ## Documentation Links 59 | 60 | - [package links](https://getcomposer.org/doc/04-schema.md#package-links) 61 | - [autoload `classmap`](https://getcomposer.org/doc/04-schema.md#classmap) -------------------------------------------------------------------------------- /case-study/laps.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Laps 3 | subtitle: case study 4 | --- 5 | 6 | - development repository : [GitHub](https://github.com/Rarst/laps) 7 | - Composer repository : [Packagist](https://packagist.org/packages/rarst/laps) 8 | - versioning : semantic 9 | - dependencies : [Symfony Stopwatch](https://symfony.com/doc/current/components/stopwatch.html), [mustache.php](https://github.com/bobthecow/mustache.php) 10 | - development dependencies : [Twitter Bootstrap](http://getbootstrap.com/) 11 | 12 | ## Development 13 | 14 | Laps is light profiler plugin for WordPress. It was developed exclusively as Composer package. 15 | 16 | `classmap` autoload type is used for classes, since files adhere to WordPress naming convention and need to be handled by static scan on install. 17 | 18 | Stopwatch component from [Symfony framework](http://symfony.com/) and PHP port of [mustache templating language ](http://mustache.github.io/) are required as Composer dependencies and used for timing events and templating output respectively. 19 | 20 | Composer package for Twitter Bootstrap is required as development dependency to make use of importing styles and scripts from its source. 21 | 22 | `composer/installers` package and `wordpress-plugin` type are declared for [path customization](/recipe/paths-control) when plugin is installed as part of [whole site stack](/recipe/site-stack). 23 | 24 | ## composer.json 25 | 26 | ```json 27 | { 28 | "name" : "rarst/laps", 29 | "description": "Light WordPress profiler.", 30 | "keywords" : ["wordpress", "performance"], 31 | "type" : "wordpress-plugin", 32 | "homepage" : "https://github.com/Rarst/laps", 33 | "license" : "MIT", 34 | "authors" : [ 35 | { 36 | "name" : "Andrey Savchenko", 37 | "homepage": "https://www.rarst.net/" 38 | } 39 | ], 40 | "support" : { 41 | "issues": "https://github.com/Rarst/laps/issues" 42 | }, 43 | "autoload" : { 44 | "classmap": ["src/"] 45 | }, 46 | "require" : { 47 | "composer/installers": "~1.0", 48 | "symfony/stopwatch" : "~2.4", 49 | "mustache/mustache" : "~2.4" 50 | }, 51 | "require-dev": { 52 | "twbs/bootstrap": "~3.2" 53 | } 54 | } 55 | ``` 56 | 57 | ## Documentation Links 58 | 59 | - [package links](https://getcomposer.org/doc/04-schema.md#package-links) 60 | - [autoload `classmap`](https://getcomposer.org/doc/04-schema.md#classmap) -------------------------------------------------------------------------------- /case-study/scbframework.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: scbFramework 3 | subtitle: case study 4 | --- 5 | 6 | - development repository : [GitHub](https://github.com/scribu/wp-scb-framework) 7 | - Composer repository : [Packagist](https://packagist.org/packages/scribu/scb-framework) 8 | - Composer support issue : [#28](https://github.com/scribu/wp-scb-framework/issues/28) 9 | - Composer implementation pull request : [#29](https://github.com/scribu/wp-scb-framework/pull/29) 10 | - versioning : development only 11 | - no dependencies 12 | 13 | ## Changes 14 | 15 | scbFramework is a set of helper classes and functions to be used in extensions. 16 | 17 | Library includes elaborate custom loader to handle case when multiple instances are included. Composer autoload was added in parallel to it on assumption of shared use as dependency: 18 | 19 | - classes autoload is built by static scan via `classmap` autoload type 20 | - one of the files additionally has function definitions and unconditionally included via `files` autoload type 21 | - alternate bootstrap file is included in autoload, bypassing custom loader completely 22 | 23 | Custom loader is preserved and remains functional for non-Composer use. 24 | 25 | Since library is not being semantically versioned from Composer point of view it is available as rolling development branch to be used with `*@dev` version constraint. 26 | 27 | ## composer.json 28 | 29 | ```json 30 | { 31 | "name" : "scribu/scb-framework", 32 | "description": "A set of useful classes for faster plugin development", 33 | "keywords" : ["wordpress"], 34 | "homepage" : "https://github.com/scribu/wp-scb-framework", 35 | "license" : "GPL-3.0+", 36 | "authors" : [ 37 | { 38 | "name" : "Cristi Burcă", 39 | "homepage": "http://scribu.net/" 40 | } 41 | ], 42 | "support" : { 43 | "issues": "https://github.com/scribu/wp-scb-framework/issues", 44 | "source": "https://github.com/scribu/wp-scb-framework", 45 | "wiki" : "https://github.com/scribu/wp-scb-framework/wiki" 46 | }, 47 | "autoload" : { 48 | "classmap": ["."], 49 | "files" : ["load-composer.php", "Util.php"] 50 | } 51 | } 52 | ``` 53 | 54 | ## Documentation Links 55 | 56 | - [autoload `classmap`](https://getcomposer.org/doc/04-schema.md#classmap) 57 | - [autoload `files`](https://getcomposer.org/doc/04-schema.md#files) -------------------------------------------------------------------------------- /case-study/tlc-transients.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: TLC Transients 3 | subtitle: case study 4 | --- 5 | 6 | - development repository : [GitHub](https://github.com/markjaquith/WP-TLC-Transients) 7 | - Composer repository : [Packagist](https://packagist.org/packages/markjaquith/wp-tlc-transients) 8 | - Composer support issue : [#16](https://github.com/markjaquith/WP-TLC-Transients/issues/16) 9 | - Composer implementation pull request : [#17](https://github.com/markjaquith/WP-TLC-Transients/pull/17) 10 | - versioning : semantic 11 | - no dependencies 12 | 13 | ## Changes 14 | 15 | TLC Transients library is wrapper for the WordPress Transients API, which provides additional functionality for use in extensions. 16 | 17 | Library was originally single monolithic file with class/function definitions and bootstrap code. For Composer support code was reorganized by breaking out definitions into individual files. 18 | 19 | Since WordPress has own coding style convention for class and file naming, `classmap` autoload type in Composer is used to build class map via static scan on install. `files` autoload is additionally used to unconditionally include functions definition file. 20 | 21 | Bootstrap code includes definitions explicitly (if Composer autoload is not used) and is fully compatible with non-Composer use. 22 | 23 | ## composer.json 24 | 25 | ```json 26 | { 27 | "name" : "markjaquith/wp-tlc-transients", 28 | "description": "A WP transients interface with support for soft-expiration, background updating of the transients.", 29 | "keywords" : ["wordpress", "cache"], 30 | "homepage" : "https://github.com/markjaquith/WP-TLC-Transients", 31 | "license" : "GPL-2.0+", 32 | "authors" : [ 33 | { 34 | "name" : "Mark Jaquith", 35 | "homepage": "http://markjaquith.com/" 36 | } 37 | ], 38 | "support" : { 39 | "issues": "https://github.com/markjaquith/WP-TLC-Transients/issues", 40 | "source": "https://github.com/markjaquith/WP-TLC-Transients" 41 | }, 42 | "autoload" : { 43 | "classmap": ["class-tlc-transient.php", "class-tlc-transient-update-server.php"], 44 | "files" : ["functions.php"] 45 | } 46 | } 47 | ``` 48 | 49 | ## Documentation Links 50 | 51 | - [autoload `classmap`](https://getcomposer.org/doc/04-schema.md#classmap) 52 | - [autoload `files`](https://getcomposer.org/doc/04-schema.md#files) 53 | -------------------------------------------------------------------------------- /case-study/wordpress-seo.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: WordPress SEO by Yoast 3 | subtitle: case study 4 | --- 5 | 6 | - development repository : [GitHub](https://github.com/Yoast/wordpress-seo) 7 | - Composer repository : [Packagist](https://packagist.org/packages/yoast/wordpress-seo) 8 | - versioning : custom 9 | - Composer support issue : [#1890](https://github.com/Yoast/wordpress-seo/issues/1890) 10 | - Composer implementation pull request : [#1912](https://github.com/Yoast/wordpress-seo/pull/1912) 11 | - dependencies : own libraries, [PHP 5.2 autoloader](https://bitbucket.org/xrstf/composer-php52) 12 | - development dependencies : [Yoast Coding Standards](https://github.com/Yoast/yoastcs) 13 | 14 | ## Changes 15 | 16 | WordPress SEO is one of the most popular WordPress plugins, with long running history of development. 17 | While it had basic `composer.json` for a while, it wasn’t properly functioning since introduction of vendor own’s dependencies via Git submodules. 18 | 19 | For new Composer implementation dependencies were converted to Composer packages. 20 | Additionally [PHP CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) ruleset, used for unit testing and development, was also converted to package for sharing between projects. 21 | 22 | `classmap` autoload type is used for classes, since files adhere to WordPress naming convention and need to be handled by static scan on install. 23 | To retain compatibility to PHP 5.2 environment special loader is required as dependency and run via scripts to generate compatible version. 24 | 25 | `composer/installers` package and `wordpress-plugin` type are declared for [path customization](/recipe/paths-control) when plugin is installed as part of [whole site stack](/recipe/site-stack). 26 | 27 | `scripts` are used to automate configuration of coding style and trigger builds of special autoloader. 28 | 29 | ## composer.json 30 | 31 | ```json 32 | { 33 | "name": "yoast/wordpress-seo", 34 | "description": "Improve your WordPress SEO: Write better content and have a fully optimized WordPress site using the WordPress SEO plugin by Yoast.", 35 | "keywords": [ 36 | "wordpress", 37 | "seo" 38 | ], 39 | "homepage": "https://yoast.com/wordpress/plugins/seo/", 40 | "license": "GPL-2.0+", 41 | "authors": [ 42 | { 43 | "name": "Team Yoast", 44 | "email": "support@yoast.com", 45 | "homepage": "https://yoast.com" 46 | } 47 | ], 48 | "type": "wordpress-plugin", 49 | "support": { 50 | "issues": "https://github.com/Yoast/wordpress-seo/issues", 51 | "forum": "https://wordpress.org/support/plugin/wordpress-seo", 52 | "wiki": "https://github.com/Yoast/wordpress-seo/wiki", 53 | "source": "https://github.com/Yoast/wordpress-seo" 54 | }, 55 | "require": { 56 | "composer/installers": "~1.0", 57 | "yoast/license-manager": "dev-master", 58 | "yoast/i18n-module": "dev-master", 59 | "xrstf/composer-php52": "^1.0.17" 60 | }, 61 | "require-dev": { 62 | "yoast/yoastcs": "dev-master" 63 | }, 64 | "minimum-stability": "dev", 65 | "autoload": { 66 | "classmap": [ 67 | "admin/", 68 | "frontend/", 69 | "inc/" 70 | ] 71 | }, 72 | "scripts": { 73 | "config-yoastcs": [ 74 | "\"vendor/bin/phpcs\" --config-set installed_paths ../../../vendor/wp-coding-standards/wpcs,../../../vendor/yoast/yoastcs", 75 | "\"vendor/bin/phpcs\" --config-set default_standard Yoast" 76 | ], 77 | "post-install-cmd": [ 78 | "xrstf\\Composer52\\Generator::onPostInstallCmd" 79 | ], 80 | "post-update-cmd": [ 81 | "xrstf\\Composer52\\Generator::onPostInstallCmd" 82 | ], 83 | "post-autoload-dump": [ 84 | "xrstf\\Composer52\\Generator::onPostInstallCmd" 85 | ] 86 | } 87 | } 88 | ``` 89 | 90 | ## Documentation Links 91 | 92 | - [package links](https://getcomposer.org/doc/04-schema.md#package-links) 93 | - [autoload `classmap`](https://getcomposer.org/doc/04-schema.md#classmap) 94 | - [scripts](https://getcomposer.org/doc/articles/scripts.md) -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rarst/composer-in-wp/d72adb65db83d967001414c5cea800b215060a8a/favicon.ico -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Your Guide to Composer in WordPress 3 | excerpt: Making use of Composer for WordPress sites and extensions 4 | frontpage: true 5 | --- 6 | This site was asked for too many times to not happen. Think of it as unofficial companion to [Composer documentation](https://getcomposer.org/doc/) for WordPress developers. 7 | 8 | ### Prerequisites 9 | 10 | Install Composer by following instructions in documentation for [*nix](https://getcomposer.org/doc/00-intro.md#installation-nix) or [Windows](https://getcomposer.org/doc/00-intro.md#installation-windows). 11 | 12 | ## Why Bother 13 | 14 | Composer is **dependency manager** command line utility and accompanying infrastructure tools. It is made in PHP and for PHP. 15 | 16 | It can help you improve how you **develop, share, make use of, host, and deploy** your WordPress code and whole site stacks. 17 | 18 | ### Dependency 19 | 20 | So what is “dependency”? Basic building block of Composer world is “package” and it is: 21 | 22 | - a folder (or file) 23 | - probably with PHP code 24 | - preferably with `composer.json` file 25 | - preferably [semantically versioned](https://semver.org/) 26 | 27 | So pretty much anything can be package. Packages preferably contain information that Composer can read and process. That information can include which other packages at which versions are required as dependencies. 28 | 29 | In WordPress world Composer package can be: 30 | 31 | - WordPress core itself 32 | - extension (plugin or theme) 33 | - whole site (with core, themes, and plugins as dependencies) 34 | 35 | It also opens up a way to depend on (and share) generic PHP libraries, without embedding their sources. 36 | 37 | There is also special kind of [platform package](https://getcomposer.org/doc/02-libraries.md#platform-packages) dependency. It allows to depend on specific PHP version and extensions. 38 | 39 | ### Manager 40 | 41 | Packages are not of much use somewhere out there. That is why from a starting point (“root” package) Composer will: 42 | 43 | - calculate its dependencies 44 | - download them (or retrieve from local cache) 45 | - organize them into directories 46 | - produce combined class autoload file 47 | 48 | Composer thrives on compatibility and packages can come from: 49 | 50 | - [Composer repositories](https://getcomposer.org/doc/05-repositories.md#composer) 51 | - direct downloads 52 | - version control systems 53 | - [Subversion](http://subversion.apache.org/) 54 | - [Git](https://git-scm.com/) (+ [GitHub](https://github.com/) downloads) 55 | - [Mercurial](https://www.mercurial-scm.org/) (+ [Bitbucket](https://bitbucket.org/) downloads) 56 | - [PEAR](http://pear.php.net/) channels 57 | - [artifacts](https://getcomposer.org/doc/05-repositories.md#artifact) (local ZIP archives) 58 | 59 | ## Recipes 60 | 61 | This site will provide you with information on how to: 62 | 63 | - [create package for WordPress core](/recipe/core-package) 64 | - [control plugins and themes paths](/recipe/paths-control) 65 | - [create whole site Composer package](/recipe/site-stack) 66 | 67 | 68 | ## Case Studies 69 | 70 | Theory is no replacement for experience and there are already practical examples of using Composer with WordPress code (old and new) available. 71 | 72 | ### Updating for Composer 73 | 74 | - [WordPress SEO](/case-study/wordpress-seo) plugin by team Yoast 75 | - [TLC Transients](/case-study/tlc-transients) library by Mark Jaquith 76 | - [scbFramework](/case-study/scbframework) library by Cristi “scribu” Burcă 77 | 78 | ### Developing for Composer 79 | 80 | - [Laps](/case-study/laps) plugin by Andrey “Rarst” Savchenko 81 | - [Fragment Cache](/case-study/fragment-cache) plugin by Andrey “Rarst” Savchenko -------------------------------------------------------------------------------- /recipe/core-package.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Core Package 3 | subtitle: recipe 4 | description: How to create Composer package for WordPress core 5 | --- 6 | 7 |
You can skip this and use johnpbloch/wordpress package.
8 | 9 | Composer works best with code accompanied by `composer.json` and that is something WordPress core hadn’t adopted yet. There is a bit of tinkering involved to create shim package for core. 10 | 11 | ## Create Custom Package 12 | 13 | Package description follows same rules as `composer.json` file, with addition of version and where to download distribution and/or source from. 14 | 15 | With Composer-aware projects these are usually automagically inferred from combination of `composer.json` and version control. Tags and branches serve as versions, version control itself and APIs for archives (for GitHub and Bitbucket) as downloads. 16 | 17 | For Composer-unaware project the mechanics are much the same, but the downside is that we need to define package for every version individually. 18 | 19 | ### Release Package 20 | 21 | Package for a specific release version of WordPress can be defined like this: 22 | 23 | ```json 24 | { 25 | "type" : "package", 26 | "package": { 27 | "name" : "rarst/wordpress", 28 | "type" : "wordpress-core", 29 | "version": "3.6", 30 | "dist" : { 31 | "url" : "http://wordpress.org/wordpress-3.6.zip", 32 | "type": "zip" 33 | }, 34 | "source" : { 35 | "url" : "https://github.com/WordPress/WordPress", 36 | "type" : "git", 37 | "reference": "3.6" 38 | }, 39 | "require": { 40 | "johnpbloch/wordpress-core-installer": "~0.1" 41 | } 42 | } 43 | } 44 | ``` 45 | 46 | - for name I am declaring it in my own `rarst/*` vendor namespace, so it doesn’t conflict with anything 47 | - `wordpress-core` type and `johnpbloch/wordpress-core-installer` dependency serve to allow clean path customization (otherwise Composer will try to nest core in a vendor directory), see [site stack recipe](/recipe/site-stack) for details 48 | - distribution points to simple direct download from official site 49 | - source points to the release tag at official GitHub mirror, although original Subversion repository would work as well 50 | 51 | ## Require Package in Project 52 | 53 | Now that you have package definition you can drop it into right into `composer.json` of site package, [`repositories : []` field](https://getcomposer.org/doc/04-schema.md#repositories). Easy, but gets bulky fast for multiple versions. 54 | 55 | More organized approach is to [host your own Satis repository](https://getcomposer.org/doc/articles/handling-private-packages-with-satis.md) and have it process packages. 56 | 57 | Then making use of it in project becomes: 58 | 59 | ```json 60 | { 61 | "repositories" : [ 62 | { 63 | "type" : "composer", 64 | "url" : "http://rarst.net" 65 | } 66 | ], 67 | "require" : { 68 | "rarst/wordpress" : ">=3.6" 69 | } 70 | } 71 | ``` 72 | 73 | This will have Composer look at [rarst.net/packages.json](https://www.rarst.net/packages.json) during install and pick appropriate package version to use. 74 | 75 | ## Documentation Links 76 | 77 | - [package links](https://getcomposer.org/doc/04-schema.md#package-links) 78 | - [package repository](https://getcomposer.org/doc/05-repositories.md#package-2) -------------------------------------------------------------------------------- /recipe/paths-control.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Paths Control 3 | subtitle: recipe 4 | description: How to use composer/installers to control WordPress theme and plugin paths 5 | --- 6 | 7 | The default type of Composer package is `library`. Composer puts such packages in `vendor/[vendor]/[name]`, which does not fit typical WordPress directory layout well. 8 | 9 | However it is easy adjust it. 10 | 11 | ## Require composer/installers 12 | 13 | [`composer/installers`](https://github.com/composer/installers) is a package of special `composer-installer` type. It catches packages with non-`library` types during installation and (if they match types it supports) adjusts their paths. 14 | 15 | To make use of it your extension's `composer.json` should contain: 16 | 17 | ```json 18 | { 19 | "type" : "wordpress-plugin", 20 | "require" : { 21 | "composer/installers" : "~1.0" 22 | } 23 | } 24 | ``` 25 | 26 | Type can also be `wordpress-theme` and `wordpress-muplugin`. 27 | 28 | When used in root [site stack package](/recipe/site-stack) it would make packages go into `wp-content/*` directories as WordPress things usually do. 29 | 30 | ## Customize paths 31 | 32 | If you don't like defaults you can override them in root package (and there only, one of things only root one gets to decide) individually or in bulk: 33 | 34 | ```json 35 | { 36 | "extra" : { 37 | "installer-paths" : { 38 | "content/plugins/{$name}/": ["type:wordpress-plugin"] 39 | } 40 | } 41 | } 42 | ``` 43 | 44 | Note that this **only** works for packages that declare `composer/installers` support. You cannot customize paths for generic `library` packages. However you can customize location of `vendor` directory to rename and/or move from default root location: 45 | 46 | ```json 47 | { 48 | "config" : { 49 | "vendor-dir" : "wp-content/vendor" 50 | } 51 | } 52 | ``` 53 | 54 | ## Documentation Links 55 | 56 | - [package type](https://getcomposer.org/doc/04-schema.md#type) 57 | - [package links](https://getcomposer.org/doc/04-schema.md#package-links) 58 | - [extra property](https://getcomposer.org/doc/04-schema.md#extra) 59 | - [config property](https://getcomposer.org/doc/04-schema.md#config) -------------------------------------------------------------------------------- /recipe/site-stack.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Site Stack 3 | subtitle: recipe 4 | description: composer.json example for whole WordPress site Composer stack 5 | --- 6 | 7 | The whole site stack package is end game of using Composer with WordPress. 8 | 9 | ## composer.json 10 | 11 | It would depend on your project what exactly to put in a package and how to configure it. 12 | 13 | For example it can be something like this ([original gist](https://gist.github.com/Rarst/5300767)) : 14 | 15 | ```json 16 | { 17 | "name" : "rarst/install-test", 18 | "description" : "Test project for WordPress stack via Composer", 19 | "authors" : [ 20 | { 21 | "name" : "Andrey Savchenko", 22 | "homepage": "https://www.Rarst.net/" 23 | } 24 | ], 25 | "type" : "project", 26 | "repositories": [ 27 | { 28 | "type": "composer", 29 | "url" : "https://wpackagist.org" 30 | } 31 | ], 32 | "config" : { 33 | "vendor-dir": "wp-content/vendor" 34 | }, 35 | "require" : { 36 | "johnpbloch/wordpress" : ">=4.9", 37 | "rarst/fragment-cache" : "^1.3", 38 | "rarst/update-blocker" : "^1.1" 39 | }, 40 | "require-dev" : { 41 | "rarst/laps" : "^1.4.4", 42 | "rarst/toolbar-theme-switcher" : "^1.5", 43 | "wpackagist-plugin/a-fresher-cache" : "*", 44 | "wpackagist-plugin/core-control" : "*", 45 | "wpackagist-plugin/monster-widget" : "*", 46 | "wpackagist-plugin/theme-check" : "*", 47 | "wpackagist-plugin/user-switching" : "*", 48 | "wpackagist-plugin/wcm-user-language-switcher": "*" 49 | }, 50 | "extra" : { 51 | "wordpress-install-dir": "wp" 52 | } 53 | } 54 | ``` 55 | 56 | ## Breakdown 57 | 58 | - name is within my `rarst/*` vendor namespace 59 | - `type` is set to `project` (rather than default `library`), it is mostly semantic hint that this is root package 60 | - `repositories` declare [WordPress Packagist](https://wpackagist.org/) proxy for Composer access to official WordPress plugin repository 61 | - `vendor` directory is relocated inside `wp-content` 62 | - WordPress core, custom theme and number of plugins are listed as dependencies, part of them as for optional development context 63 | - WordPress [core package](/recipe/core-package) is configured to go into `wp` subdirectory (using custom `wordpress-install-dir` configuration option of core installer, required by core package) 64 | 65 | ## Installation 66 | 67 | ### From Local File 68 | 69 | 1. [Download `composer.json` from gist](https://gist.githubusercontent.com/Rarst/5300767/raw/composer.json) into empty directory 70 | 2. Run `composer install --prefer-dist` in that directory 71 | 72 | ### From Remote Repository 73 | 74 | Run: 75 | 76 | ```bash 77 | composer create-project rarst/install-test wordpress dev-master --repository-url=https://www.rarst.net --prefer-dist 78 | ``` 79 | 80 | This will tell Composer to create project: 81 | 82 | - from `rarst/install-test` package 83 | - in `wordpress` directory 84 | - at `dev-master` version 85 | - using custom [`rarst.net/packages.json`](https://www.rarst.net/packages.json) Composer repository 86 | - favor direct downloads of packages over cloning from version control 87 | 88 | ### Result 89 | 90 | After install the project directory will have the following content: 91 | 92 | - `wp` WordPress core 93 | - `wp-content` 94 | - `plugins` 95 | - packages of `wordpress-plugin` type 96 | - `themes` 97 | - packages of `wordpress-theme` type 98 | - `vendor` 99 | - packages of `library` type 100 | - `autoload.php` combined class autoload file for all packages 101 | - `composer.json` project file we ran install for 102 | - `composer.lock` file with exact current state of packages 103 | - `wp-config.php` was not created by this example, but should be placed here 104 | 105 | In one command we have neat and nearly complete subdirectory install! The example package we used only lacks properly set up `wp-config.php` and `index.php` for complete WordPress site. 106 | 107 | ## WordPress configuration 108 | 109 | ### Directories 110 | 111 | Notably we made changes to the default WordPress directory structure, which you might be used to. This enables us to update parts of it separately, without worry that core update erases content packages inside of it. 112 | 113 | This is supported natively by WordPress configuration, see documentation in Codex: 114 | 115 | 1. [Giving WordPress Its Own Directory](https://codex.wordpress.org/Giving_WordPress_Its_Own_Directory) (you likely want Method II with simpler and more robust rewrite setup) 116 | 2. [Moving wp-content folder](https://wordpress.org/support/article/editing-wp-config-php/#moving-wp-content-folder) 117 | 118 | ### Autoload 119 | 120 | Since our whole stack shares single Composer–driven autoload for classes — we need to include it into WordPress boot process. 121 | 122 | There is no native WordPress convention for autoload and in practice `wp-config.php` is most appropriate place to set it up. 123 | 124 | For example it might look like this at the top of `wp-config.php` (created at the root, one level above core subdirectory): 125 | 126 | ```php 127 | require __DIR__ . '/wp-content/vendor/autoload.php'; 128 | ``` 129 | 130 | ## Documentation Links 131 | 132 | - [package properties](https://getcomposer.org/doc/04-schema.md#properties) 133 | - [`composer install` command](https://getcomposer.org/doc/03-cli.md#install) 134 | - [`composer create-project` command](https://getcomposer.org/doc/03-cli.md#create-project) 135 | -------------------------------------------------------------------------------- /resources.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Resources 3 | excerpt: Links to resources about Composer and its integration with WordPress 4 | --- 5 | 6 | Compilation of links to online resources about, for, and near Composer. 7 | 8 | ## Documentation 9 | 10 | - [Composer documentation](https://getcomposer.org/doc/) 11 | - Composer [GitHub project](https://github.com/composer/composer) and [issue tracker](https://github.com/composer/composer/issues) 12 | - [interactive `composer.json` cheat sheet](http://composer.json.jolicode.com/) 13 | 14 | ## Specifications 15 | 16 | - [`composer.json` technical schema](https://github.com/composer/composer/blob/master/res/composer-schema.json) — check against with [`composer validate` command](https://getcomposer.org/doc/03-cli.md#validate) 17 | - [SPDX license identifiers](https://github.com/composer/spdx-licenses/blob/master/res/spdx-licenses.json) recognized by Composer 18 | - [Semantic Versioning](https://semver.org/) 19 | 20 | ## Repositories 21 | 22 | - [Packagist](https://packagist.org/) ([GitHub](https://github.com/composer/packagist)) 23 | - [WordPress Packagist](https://wpackagist.org/) ([GitHub](https://github.com/outlandishideas/wpackagist)) 24 | 25 | ## Packages 26 | 27 | - [composer/installers](https://github.com/composer/installers) ([Packagist](https://packagist.org/packages/composer/installers)) — custom installer for frameworks’ paths (including WordPress extensions) 28 | - [johnpbloch/wordpress](https://github.com/johnpbloch/wordpress) ([Packagist](https://packagist.org/packages/johnpbloch/wordpress)) — automated fork of WordPress core, adding Composer support 29 | - [johnpbloch/wordpress-core-installer](https://github.com/johnpbloch/wordpress-core-installer) ([Packagist](https://packagist.org/packages/johnpbloch/wordpress-core-installer)) — custom installer for WordPress core to cleanly customize subdirectory path 30 | - [rarst/locate-vendor](https://github.com/Rarst/locate-vendor) ([Packagist](https://packagist.org/packages/rarst/locate-vendor)) — small experimental helper to resolve vendor folder location 31 | 32 | ## People 33 | 34 | - [Nils Adermann](http://www.naderman.de/) ([@naderman](https://twitter.com/naderman)) — Composer developer 35 | - [Jordi Boggiano](http://nelm.io/jordi) ([@seldaek](https://twitter.com/seldaek)) — Composer developer 36 | - [Andrey Savchenko](https://www.rarst.net/) ([@Rarst](https://twitter.com/Rarst)) — made this site so gets to plug himself all over it 37 | - [Tamlyn Rhodes](https://tamlyn.org/) ([@tamlyn](https://twitter.com/tamlyn)) — WordPress Packagist developer 38 | - [John P Bloch](https://johnpbloch.com/) — WordPress core installer developer 39 | - [#ComposerPHP](https://twitter.com/search/%23ComposerPHP) on Twitter 40 | 41 | ## Stacks 42 | 43 | - [WordPlate](https://wordplate.github.io/) 44 | - [Bedrock](https://roots.io/bedrock/) 45 | 46 | ## Tools 47 | 48 | - [Satis](https://github.com/composer/satis) ([Packagist](https://packagist.org/packages/composer/satis)) — static Composer repository generator 49 | - [Private Packagist](https://packagist.com/) — Composer package archive as a service for private source code and redundant infrastructure 50 | - [Release Belt](https://github.com/Rarst/release-belt) — Composer repository implementation to easily host ZIP release archives. 51 | 52 | ## IDE 53 | 54 | - [PhpStorm](http://www.jetbrains.com/phpstorm/) 55 | - [Composer support](http://www.jetbrains.com/phpstorm/webhelp/composer.html) 56 | -------------------------------------------------------------------------------- /serve.cmd: -------------------------------------------------------------------------------- 1 | bundle exec jekyll serve -------------------------------------------------------------------------------- /slides.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: null 3 | sitemap: false 4 | --- 5 | 6 | 7 | 8 | 9 | 10 | 13 | 14 | Better Site Stacks with Composer 15 | 16 | If you are not redirected automatically, follow the link. --------------------------------------------------------------------------------