+
+
+
+
diff --git a/_posts/2014-05-07-New-Website.md b/_posts/2014-05-07-New-Website.md
new file mode 100644
index 0000000..174ef23
--- /dev/null
+++ b/_posts/2014-05-07-New-Website.md
@@ -0,0 +1,6 @@
+---
+layout: default
+title: New Website and new Logo!
+---
+
+Welcome to the new website!
diff --git a/about/index.html b/about/index.html
new file mode 100644
index 0000000..7369c38
--- /dev/null
+++ b/about/index.html
@@ -0,0 +1,30 @@
+---
+layout: default
+title: About PHPCR
+overview: true
+---
+
+
What is it?
+
+ The PHP Content Repository is an adaption of the Java Content Repository (JCR) standard, an open API specification defined in JSR-283.
+ The API defines how to handle hierarchical semi-structured data in a consistent way.
+
+
+ The typical use case is content management systems.
+ PHPCR combines the best out of document-oriented databases (weak structured data) and of XML databases (hierarchical trees). On top of that, it adds useful features like searching, versioning, access control and locking on top of it.
+
+
+
When to use PHPCR
+
+
For hierarchical navigation structures
+
For compound data that belongs together. i.e. a web page with attached files or translations
+
You need to version content
+
You want full text search
+
+
+
When not to use PHPCR
+
+ PHPCR is targeted at semi structured content. For strictly structured content and when using aggregation queries, we recommend using relational databases.
+ For example: A web shop where products are stored in PHPCR, orders are stored in a relational database.
+
+
diff --git a/assets/images/logo.png b/assets/images/logo.png
new file mode 100644
index 0000000..7abe589
Binary files /dev/null and b/assets/images/logo.png differ
diff --git a/assets/main.css b/assets/main.css
new file mode 100644
index 0000000..28270a2
--- /dev/null
+++ b/assets/main.css
@@ -0,0 +1,252 @@
+body {
+ color: #777;
+}
+
+.pure-img-responsive {
+ max-width: 100%;
+ height: auto;
+}
+
+/*
+Add transition to containers so they can push in and out.
+*/
+#layout,
+#menu,
+.menu-link {
+ -webkit-transition: all 0.2s ease-out;
+ -moz-transition: all 0.2s ease-out;
+ -ms-transition: all 0.2s ease-out;
+ -o-transition: all 0.2s ease-out;
+ transition: all 0.2s ease-out;
+}
+
+/*
+This is the parent `
` that contains the `.pure-menu` that
+appears on the left side of the page.
+*/
+
+#menu .logo {
+ text-align: center;
+ margin: 20px 0px;
+}
+
+#menu {
+ margin-left: -200px; /* "#menu" width */
+ width: 200px;
+ position: fixed;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ z-index: 1000; /* so the menu or its navicon stays above all content */
+ background: #191818;
+ overflow-y: auto;
+ -webkit-overflow-scrolling: touch;
+}
+ /*
+ All anchors inside the menu should be styled like this.
+ */
+ #menu a {
+ color: #999;
+ border: none;
+ padding: 0.6em 0 0.6em 0.6em;
+ }
+
+ /*
+ Remove all background/borders, since we are applying them to #menu.
+ */
+ #menu .pure-menu,
+ #menu .pure-menu ul {
+ border: none;
+ background: transparent;
+ }
+
+ /*
+ Add that light border to separate items into groups.
+ */
+ #menu .pure-menu ul,
+ #menu .pure-menu .menu-item-divided {
+ border-top: 1px solid #333;
+ }
+ /*
+ Change color of the anchor links on hover/focus.
+ */
+ #menu .pure-menu li a:hover,
+ #menu .pure-menu li a:focus {
+ background: #333;
+ }
+
+ /*
+ This styles the selected menu item `
`.
+ */
+ #menu .pure-menu-selected,
+ #menu .pure-menu-heading {
+ background: #1f8dd6;
+ }
+ /*
+ This styles a link within a selected menu item `
`.
+ */
+ #menu .pure-menu-selected a {
+ color: #fff;
+ }
+
+ /*
+ This styles the menu heading.
+ */
+ #menu .pure-menu-heading {
+ font-size: 110%;
+ color: #fff;
+ margin: 0;
+ }
+
+ #menu a:hover {
+ background-color: #000;
+ }
+
+ #menu .pure-menu-selected a:hover {
+ background: #1f8dd6;
+ }
+
+/* -- Dynamic Button For Responsive Menu -------------------------------------*/
+
+/*
+The button to open/close the Menu is custom-made and not part of Pure. Here's
+how it works:
+*/
+
+
+/*
+`.menu-link` represents the responsive menu toggle that shows/hides on
+small screens.
+*/
+.menu-link {
+ position: fixed;
+ display: block; /* show this only on small screens */
+ top: 0;
+ left: 0; /* "#menu width" */
+ background: #000;
+ background: rgba(0,0,0,0.7);
+ font-size: 10px; /* change this value to increase/decrease button size */
+ z-index: 10;
+ width: 2em;
+ height: auto;
+ padding: 2.1em 1.6em;
+}
+
+ .menu-link:hover,
+ .menu-link:focus {
+ background: #000;
+ }
+
+ .menu-link span {
+ position: relative;
+ display: block;
+ }
+
+ .menu-link span,
+ .menu-link span:before,
+ .menu-link span:after {
+ background-color: #fff;
+ width: 100%;
+ height: 0.2em;
+ }
+
+ .menu-link span:before,
+ .menu-link span:after {
+ position: absolute;
+ margin-top: -0.6em;
+ content: " ";
+ }
+
+ .menu-link span:after {
+ margin-top: 0.6em;
+ }
+
+
+/* -- Responsive Styles (Media Queries) ------------------------------------- */
+
+/*
+Hides the menu at `48em`, but modify this based on your app's needs.
+*/
+@media (min-width: 48em) {
+
+ .header,
+ .content {
+ padding-left: 2em;
+ padding-right: 2em;
+ }
+
+ #layout {
+ padding-left: 200px; /* left col width "#menu" */
+ left: 0;
+ }
+ #menu {
+ left: 200px;
+ }
+
+ .menu-link {
+ position: fixed;
+ left: 200px;
+ display: none;
+ }
+
+ #layout.active .menu-link {
+ left: 200px;
+ }
+}
diff --git a/assets/pure-min.css b/assets/pure-min.css
new file mode 100644
index 0000000..2def7b9
--- /dev/null
+++ b/assets/pure-min.css
@@ -0,0 +1,11 @@
+/*!
+Pure v0.5.0-rc-1
+Copyright 2014 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+https://github.com/yui/pure/blob/master/LICENSE.md
+*/
+/*!
+normalize.css v1.1.3 | MIT License | git.io/normalize
+Copyright (c) Nicolas Gallagher and Jonathan Neal
+*/
+/*! normalize.css v1.1.3 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-size:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}html,button,input,select,textarea{font-family:sans-serif}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}h2{font-size:1.5em;margin:.83em 0}h3{font-size:1.17em;margin:1em 0}h4{font-size:1em;margin:1.33em 0}h5{font-size:.83em;margin:1.67em 0}h6{font-size:.67em;margin:2.33em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:1em 40px}dfn{font-style:italic}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}p,pre{margin:1em 0}code,kbd,pre,samp{font-family:monospace,serif;_font-family:'courier new',monospace;font-size:1em}pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}q{quotes:none}q:before,q:after{content:'';content:none}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,menu,ol,ul{margin:1em 0}dd{margin:0 0 0 40px}menu,ol,ul{padding:0 0 0 40px}nav ul,nav ol{list-style:none;list-style-image:none}img{border:0;-ms-interpolation-mode:bicubic}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0;white-space:normal;*margin-left:-7px}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;*overflow:visible}button[disabled],html input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0;*height:13px;*width:13px}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}[hidden]{display:none!important}.pure-img{max-width:100%;height:auto;display:block}.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%}.pure-button{display:inline-block;*display:inline;zoom:1;line-height:normal;white-space:nowrap;vertical-align:baseline;text-align:center;cursor:pointer;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.pure-button::-moz-focus-inner{padding:0;border:0}.pure-button{font-family:inherit;font-size:100%;*font-size:90%;*overflow:visible;padding:.5em 1em;color:#444;color:rgba(0,0,0,.8);*color:#444;border:1px solid #999;border:0 rgba(0,0,0,0);background-color:#E6E6E6;text-decoration:none;border-radius:2px}.pure-button-hover,.pure-button:hover,.pure-button:focus{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#1a000000', GradientType=0);background-image:-webkit-gradient(linear,0 0,0 100%,from(transparent),color-stop(40%,rgba(0,0,0,.05)),to(rgba(0,0,0,.1)));background-image:-webkit-linear-gradient(transparent,rgba(0,0,0,.05) 40%,rgba(0,0,0,.1));background-image:-moz-linear-gradient(top,rgba(0,0,0,.05) 0,rgba(0,0,0,.1));background-image:-o-linear-gradient(transparent,rgba(0,0,0,.05) 40%,rgba(0,0,0,.1));background-image:linear-gradient(transparent,rgba(0,0,0,.05) 40%,rgba(0,0,0,.1))}.pure-button:focus{outline:0}.pure-button-active,.pure-button:active{box-shadow:0 0 0 1px rgba(0,0,0,.15) inset,0 0 6px rgba(0,0,0,.2) inset}.pure-button[disabled],.pure-button-disabled,.pure-button-disabled:hover,.pure-button-disabled:focus,.pure-button-disabled:active{border:0;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);filter:alpha(opacity=40);-khtml-opacity:.4;-moz-opacity:.4;opacity:.4;cursor:not-allowed;box-shadow:none}.pure-button-hidden{display:none}.pure-button::-moz-focus-inner{padding:0;border:0}.pure-button-primary,.pure-button-selected,a.pure-button-primary,a.pure-button-selected{background-color:#0078e7;color:#fff}.pure-form input[type=text],.pure-form input[type=password],.pure-form input[type=email],.pure-form input[type=url],.pure-form input[type=date],.pure-form input[type=month],.pure-form input[type=time],.pure-form input[type=datetime],.pure-form input[type=datetime-local],.pure-form input[type=week],.pure-form input[type=number],.pure-form input[type=search],.pure-form input[type=tel],.pure-form input[type=color],.pure-form select,.pure-form textarea{padding:.5em .6em;display:inline-block;border:1px solid #ccc;box-shadow:inset 0 1px 3px #ddd;border-radius:4px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.pure-form input:not([type]){padding:.5em .6em;display:inline-block;border:1px solid #ccc;box-shadow:inset 0 1px 3px #ddd;border-radius:4px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.pure-form input[type=color]{padding:.2em .5em}.pure-form input[type=text]:focus,.pure-form input[type=password]:focus,.pure-form input[type=email]:focus,.pure-form input[type=url]:focus,.pure-form input[type=date]:focus,.pure-form input[type=month]:focus,.pure-form input[type=time]:focus,.pure-form input[type=datetime]:focus,.pure-form input[type=datetime-local]:focus,.pure-form input[type=week]:focus,.pure-form input[type=number]:focus,.pure-form input[type=search]:focus,.pure-form input[type=tel]:focus,.pure-form input[type=color]:focus,.pure-form select:focus,.pure-form textarea:focus{outline:0;outline:thin dotted \9;border-color:#129FEA}.pure-form input:not([type]):focus{outline:0;outline:thin dotted \9;border-color:#129FEA}.pure-form input[type=file]:focus,.pure-form input[type=radio]:focus,.pure-form input[type=checkbox]:focus{outline:thin dotted #333;outline:1px auto #129FEA}.pure-form .pure-checkbox,.pure-form .pure-radio{margin:.5em 0;display:block}.pure-form input[type=text][disabled],.pure-form input[type=password][disabled],.pure-form input[type=email][disabled],.pure-form input[type=url][disabled],.pure-form input[type=date][disabled],.pure-form input[type=month][disabled],.pure-form input[type=time][disabled],.pure-form input[type=datetime][disabled],.pure-form input[type=datetime-local][disabled],.pure-form input[type=week][disabled],.pure-form input[type=number][disabled],.pure-form input[type=search][disabled],.pure-form input[type=tel][disabled],.pure-form input[type=color][disabled],.pure-form select[disabled],.pure-form textarea[disabled]{cursor:not-allowed;background-color:#eaeded;color:#cad2d3}.pure-form input:not([type])[disabled]{cursor:not-allowed;background-color:#eaeded;color:#cad2d3}.pure-form input[readonly],.pure-form select[readonly],.pure-form textarea[readonly]{background:#eee;color:#777;border-color:#ccc}.pure-form input:focus:invalid,.pure-form textarea:focus:invalid,.pure-form select:focus:invalid{color:#b94a48;border-color:#ee5f5b}.pure-form input:focus:invalid:focus,.pure-form textarea:focus:invalid:focus,.pure-form select:focus:invalid:focus{border-color:#e9322d}.pure-form input[type=file]:focus:invalid:focus,.pure-form input[type=radio]:focus:invalid:focus,.pure-form input[type=checkbox]:focus:invalid:focus{outline-color:#e9322d}.pure-form select{border:1px solid #ccc;background-color:#fff}.pure-form select[multiple]{height:auto}.pure-form label{margin:.5em 0 .2em}.pure-form fieldset{margin:0;padding:.35em 0 .75em;border:0}.pure-form legend{display:block;width:100%;padding:.3em 0;margin-bottom:.3em;color:#333;border-bottom:1px solid #e5e5e5}.pure-form-stacked input[type=text],.pure-form-stacked input[type=password],.pure-form-stacked input[type=email],.pure-form-stacked input[type=url],.pure-form-stacked input[type=date],.pure-form-stacked input[type=month],.pure-form-stacked input[type=time],.pure-form-stacked input[type=datetime],.pure-form-stacked input[type=datetime-local],.pure-form-stacked input[type=week],.pure-form-stacked input[type=number],.pure-form-stacked input[type=search],.pure-form-stacked input[type=tel],.pure-form-stacked input[type=color],.pure-form-stacked select,.pure-form-stacked label,.pure-form-stacked textarea{display:block;margin:.25em 0}.pure-form-stacked input:not([type]){display:block;margin:.25em 0}.pure-form-aligned input,.pure-form-aligned textarea,.pure-form-aligned select,.pure-form-aligned .pure-help-inline,.pure-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.pure-form-aligned textarea{vertical-align:top}.pure-form-aligned .pure-control-group{margin-bottom:.5em}.pure-form-aligned .pure-control-group label{text-align:right;display:inline-block;vertical-align:middle;width:10em;margin:0 1em 0 0}.pure-form-aligned .pure-controls{margin:1.5em 0 0 10em}.pure-form input.pure-input-rounded,.pure-form .pure-input-rounded{border-radius:2em;padding:.5em 1em}.pure-form .pure-group fieldset{margin-bottom:10px}.pure-form .pure-group input{display:block;padding:10px;margin:0;border-radius:0;position:relative;top:-1px}.pure-form .pure-group input:focus{z-index:2}.pure-form .pure-group input:first-child{top:1px;border-radius:4px 4px 0 0}.pure-form .pure-group input:last-child{top:-2px;border-radius:0 0 4px 4px}.pure-form .pure-group button{margin:.35em 0}.pure-form .pure-input-1{width:100%}.pure-form .pure-input-2-3{width:66%}.pure-form .pure-input-1-2{width:50%}.pure-form .pure-input-1-3{width:33%}.pure-form .pure-input-1-4{width:25%}.pure-form .pure-help-inline,.pure-form-message-inline{display:inline-block;padding-left:.3em;color:#666;vertical-align:middle;font-size:.875em}.pure-form-message{display:block;color:#666;font-size:.875em}@media only screen and (max-width :480px){.pure-form button[type=submit]{margin:.7em 0 0}.pure-form input:not([type]),.pure-form input[type=text],.pure-form input[type=password],.pure-form input[type=email],.pure-form input[type=url],.pure-form input[type=date],.pure-form input[type=month],.pure-form input[type=time],.pure-form input[type=datetime],.pure-form input[type=datetime-local],.pure-form input[type=week],.pure-form input[type=number],.pure-form input[type=search],.pure-form input[type=tel],.pure-form input[type=color],.pure-form label{margin-bottom:.3em;display:block}.pure-group input:not([type]),.pure-group input[type=text],.pure-group input[type=password],.pure-group input[type=email],.pure-group input[type=url],.pure-group input[type=date],.pure-group input[type=month],.pure-group input[type=time],.pure-group input[type=datetime],.pure-group input[type=datetime-local],.pure-group input[type=week],.pure-group input[type=number],.pure-group input[type=search],.pure-group input[type=tel],.pure-group input[type=color]{margin-bottom:0}.pure-form-aligned .pure-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.pure-form-aligned .pure-controls{margin:1.5em 0 0}.pure-form .pure-help-inline,.pure-form-message-inline,.pure-form-message{display:block;font-size:.75em;padding:.2em 0 .8em}}.pure-menu ul{position:absolute;visibility:hidden}.pure-menu.pure-menu-open{visibility:visible;z-index:2;width:100%}.pure-menu ul{left:-10000px;list-style:none;margin:0;padding:0;top:-10000px;z-index:1}.pure-menu>ul{position:relative}.pure-menu-open>ul{left:0;top:0;visibility:visible}.pure-menu-open>ul:focus{outline:0}.pure-menu li{position:relative}.pure-menu a,.pure-menu .pure-menu-heading{display:block;color:inherit;line-height:1.5em;padding:5px 20px;text-decoration:none;white-space:nowrap}.pure-menu.pure-menu-horizontal>.pure-menu-heading{display:inline-block;*display:inline;zoom:1;margin:0;vertical-align:middle}.pure-menu.pure-menu-horizontal>ul{display:inline-block;*display:inline;zoom:1;vertical-align:middle}.pure-menu li a{padding:5px 20px}.pure-menu-can-have-children>.pure-menu-label:after{content:'\25B8';float:right;font-family:'Lucida Grande','Lucida Sans Unicode','DejaVu Sans',sans-serif;margin-right:-20px;margin-top:-1px}.pure-menu-can-have-children>.pure-menu-label{padding-right:30px}.pure-menu-separator{background-color:#dfdfdf;display:block;height:1px;font-size:0;margin:7px 2px;overflow:hidden}.pure-menu-hidden{display:none}.pure-menu-fixed{position:fixed;top:0;left:0;width:100%}.pure-menu-horizontal li{display:inline-block;*display:inline;zoom:1;vertical-align:middle}.pure-menu-horizontal li li{display:block}.pure-menu-horizontal>.pure-menu-children>.pure-menu-can-have-children>.pure-menu-label:after{content:"\25BE"}.pure-menu-horizontal>.pure-menu-children>.pure-menu-can-have-children>.pure-menu-label{padding-right:30px}.pure-menu-horizontal li.pure-menu-separator{height:50%;width:1px;margin:0 7px}.pure-menu-horizontal li li.pure-menu-separator{height:1px;width:auto;margin:7px 2px}.pure-menu.pure-menu-open,.pure-menu.pure-menu-horizontal li .pure-menu-children{background:#fff;border:1px solid #b7b7b7}.pure-menu.pure-menu-horizontal,.pure-menu.pure-menu-horizontal .pure-menu-heading{border:0}.pure-menu a{border:1px solid transparent;border-left:0;border-right:0}.pure-menu a,.pure-menu .pure-menu-can-have-children>li:after{color:#777}.pure-menu .pure-menu-can-have-children>li:hover:after{color:#fff}.pure-menu .pure-menu-open{background:#dedede}.pure-menu li a:hover,.pure-menu li a:focus{background:#eee}.pure-menu li.pure-menu-disabled a:hover,.pure-menu li.pure-menu-disabled a:focus{background:#fff;color:#bfbfbf}.pure-menu .pure-menu-disabled>a{background-image:none;border-color:transparent;cursor:default}.pure-menu .pure-menu-disabled>a,.pure-menu .pure-menu-can-have-children.pure-menu-disabled>a:after{color:#bfbfbf}.pure-menu .pure-menu-heading{color:#565d64;text-transform:uppercase;font-size:90%;margin-top:.5em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#dfdfdf}.pure-menu .pure-menu-selected a{color:#000}.pure-menu.pure-menu-open.pure-menu-fixed{border:0;border-bottom:1px solid #b7b7b7}.pure-paginator{letter-spacing:-.31em;*letter-spacing:normal;*word-spacing:-.43em;text-rendering:optimizespeed;list-style:none;margin:0;padding:0}.opera-only :-o-prefocus,.pure-paginator{word-spacing:-.43em}.pure-paginator li{display:inline-block;*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-paginator .pure-button{border-radius:0;padding:.8em 1.4em;vertical-align:top;height:1.1em}.pure-paginator .pure-button:focus,.pure-paginator .pure-button:active{outline-style:none}.pure-paginator .prev,.pure-paginator .next{color:#C0C1C3;text-shadow:0 -1px 0 rgba(0,0,0,.45)}.pure-paginator .prev{border-radius:2px 0 0 2px}.pure-paginator .next{border-radius:0 2px 2px 0}@media (max-width:480px){.pure-menu-horizontal{width:100%}.pure-menu-children li{display:block;border-bottom:1px solid #000}}.pure-table{border-collapse:collapse;border-spacing:0;empty-cells:show;border:1px solid #cbcbcb}.pure-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.pure-table td,.pure-table th{border-left:1px solid #cbcbcb;border-width:0 0 0 1px;font-size:inherit;margin:0;overflow:visible;padding:.5em 1em}.pure-table td:first-child,.pure-table th:first-child{border-left-width:0}.pure-table thead{background:#e0e0e0;color:#000;text-align:left;vertical-align:bottom}.pure-table td{background-color:transparent}.pure-table-odd td{background-color:#f2f2f2}.pure-table-striped tr:nth-child(2n-1) td{background-color:#f2f2f2}.pure-table-bordered td{border-bottom:1px solid #cbcbcb}.pure-table-bordered tbody>tr:last-child td,.pure-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.pure-table-horizontal td,.pure-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #cbcbcb}.pure-table-horizontal tbody>tr:last-child td{border-bottom-width:0}
\ No newline at end of file
diff --git a/assets/syntax.css b/assets/syntax.css
new file mode 100644
index 0000000..fc8d713
--- /dev/null
+++ b/assets/syntax.css
@@ -0,0 +1,60 @@
+.highlight { background: #eee; padding: 10px 0px 10px 0px; }
+.highlight .c { color: #999988; font-style: italic } /* Comment */
+.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
+.highlight .k { font-weight: bold } /* Keyword */
+.highlight .o { font-weight: bold } /* Operator */
+.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
+.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
+.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
+.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
+.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
+.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
+.highlight .ge { font-style: italic } /* Generic.Emph */
+.highlight .gr { color: #aa0000 } /* Generic.Error */
+.highlight .gh { color: #999999 } /* Generic.Heading */
+.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
+.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
+.highlight .go { color: #888888 } /* Generic.Output */
+.highlight .gp { color: #555555 } /* Generic.Prompt */
+.highlight .gs { font-weight: bold } /* Generic.Strong */
+.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
+.highlight .gt { color: #aa0000 } /* Generic.Traceback */
+.highlight .kc { font-weight: bold } /* Keyword.Constant */
+.highlight .kd { font-weight: bold } /* Keyword.Declaration */
+.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
+.highlight .kr { font-weight: bold } /* Keyword.Reserved */
+.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
+.highlight .m { color: #009999 } /* Literal.Number */
+.highlight .s { color: #d14 } /* Literal.String */
+.highlight .na { color: #008080 } /* Name.Attribute */
+.highlight .nb { color: #0086B3 } /* Name.Builtin */
+.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
+.highlight .no { color: #008080 } /* Name.Constant */
+.highlight .ni { color: #800080 } /* Name.Entity */
+.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
+.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
+.highlight .nn { color: #555555 } /* Name.Namespace */
+.highlight .nt { color: #000080 } /* Name.Tag */
+.highlight .nv { color: #008080 } /* Name.Variable */
+.highlight .ow { font-weight: bold } /* Operator.Word */
+.highlight .w { color: #bbbbbb } /* Text.Whitespace */
+.highlight .mf { color: #009999 } /* Literal.Number.Float */
+.highlight .mh { color: #009999 } /* Literal.Number.Hex */
+.highlight .mi { color: #009999 } /* Literal.Number.Integer */
+.highlight .mo { color: #009999 } /* Literal.Number.Oct */
+.highlight .sb { color: #d14 } /* Literal.String.Backtick */
+.highlight .sc { color: #d14 } /* Literal.String.Char */
+.highlight .sd { color: #d14 } /* Literal.String.Doc */
+.highlight .s2 { color: #d14 } /* Literal.String.Double */
+.highlight .se { color: #d14 } /* Literal.String.Escape */
+.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
+.highlight .si { color: #d14 } /* Literal.String.Interpol */
+.highlight .sx { color: #d14 } /* Literal.String.Other */
+.highlight .sr { color: #009926 } /* Literal.String.Regex */
+.highlight .s1 { color: #d14 } /* Literal.String.Single */
+.highlight .ss { color: #990073 } /* Literal.String.Symbol */
+.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
+.highlight .vc { color: #008080 } /* Name.Variable.Class */
+.highlight .vg { color: #008080 } /* Name.Variable.Global */
+.highlight .vi { color: #008080 } /* Name.Variable.Instance */
+.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
diff --git a/community/index.md b/community/index.md
new file mode 100644
index 0000000..03f9a67
--- /dev/null
+++ b/community/index.md
@@ -0,0 +1,14 @@
+---
+layout: default
+title: Community
+---
+The PHPCR project has an active community.
+
+- **Mailing List**: [http://groups.google.com/group/phpcr-users](http://groups.google.com/group/phpcr-users)
+- **IRC**: #jackalope on freenode.net
+- **Github**: [https://github.com/phpcr](https://github.com/phpcr)
+
+Additionally help may be found from within the **Symfony CMF** community:
+
+- **Mailing List**: [http://groups.google.com/group/symfony-cmf-devs](http://groups.google.com/group/symfony-cmf-devs)
+- **IRC**: #symfony-cmf on freenode.net
diff --git a/documentation/index.md b/documentation/index.md
new file mode 100644
index 0000000..8655132
--- /dev/null
+++ b/documentation/index.md
@@ -0,0 +1,21 @@
+---
+layout: default
+title: Documentation
+---
+### Tutorials
+
+- [General Guide](/documentation/tutorial/phpcr-guide.html)
+- [Integrating with Symfony](/documentation/tutorial/integrating_with_symfony.html)
+
+### Reference
+
+- [API Reference](/doc/html/index.html)
+
+### Slides
+
+- [PHPCR Introduction by David Buchmann and Lukas Smith](/slides.html)
+- [PHPCR, Une Introduction by Daniel Leech (in French)](http://phpcrtalk.dantleech.com)
+
+### Other
+
+- [PHPCR Shell](/documentation/phpcr-shell)
diff --git a/documentation/phpcr-shell/index.md b/documentation/phpcr-shell/index.md
new file mode 100644
index 0000000..d4cc53f
--- /dev/null
+++ b/documentation/phpcr-shell/index.md
@@ -0,0 +1,10 @@
+---
+layout: default
+title: PHPCR Shell
+---
+The PHPCR-Shell aims to provide a complete command line interface to any PHPCR compatible
+content repository.
+
+The latest release can be found on the [github homepage](https://github.com/phpcr/phpcr-shell).
+
+Watch this space for more documentation.
diff --git a/documentation/tutorial/integrating_with_symfony.md b/documentation/tutorial/integrating_with_symfony.md
new file mode 100644
index 0000000..f5edf5e
--- /dev/null
+++ b/documentation/tutorial/integrating_with_symfony.md
@@ -0,0 +1,6 @@
+---
+layout: default
+title: Integrating with Symfony
+---
+PHPCR can easily be integrated to symfony using the [DoctrinePHPCRBundle](http://github.com/doctrine/DoctrinePHPCRBundle).
+This bundle provides a way to easily configure and access the PHPCR session.
diff --git a/documentation/tutorial/phpcr-guide.md b/documentation/tutorial/phpcr-guide.md
new file mode 100644
index 0000000..e6d7e1a
--- /dev/null
+++ b/documentation/tutorial/phpcr-guide.md
@@ -0,0 +1,842 @@
+---
+layout: default
+title: PHPCR Guide
+---
+
+This is an introduction into the PHP content repository. You will mostly see code examples. It should work with any PHPCR implementation. We propose using [Jackalope Jackrabbit](https://github.com/jackalope/jackalope-jackrabbit) to get started as it supports all features described here.
+
+
+## Installing Jackalope
+
+Just follow the README of the [jackalope-jackrabbit](https://github.com/jackalope/jackalope-jackrabbit/blob/master/README.md) repository.
+
+
+## Navigating the contents of the content repository
+
+There are currently two options for browsing and modifying the contents of the PHPCR repository.
+
+- PHPCR Shell: Aims to provide a full command line shell interface to PHPCR content repositories. A pre-compiled PHAR archive is available on the github homepage.
+- Marmelab PHPCR Browser: A web based PHPCR browser.
+
+## In a nutshell
+
+The shortest self-contained example should output a line with 'value':
+
+{% highlight php %}
+ 'http://localhost:8080/server');
+ // end of implementation specific configuration
+
+ $factory = new $factoryclass();
+ $repository = $factory->getRepository($parameters);
+ $credentials = new \PHPCR\SimpleCredentials('admin','admin');
+ $session = $repository->login($credentials, 'default');
+ $root = $session->getRootNode();
+ $node = $root->addNode('test', 'nt:unstructured');
+ $node->setProperty('prop', 'value');
+ $session->save();
+
+ // data is stored now. in a follow-up request you can do
+ $node = $session->getNode('/test');
+ echo $node->getPropertyValue('prop'); // outputs "value"
+{% endhighlight %}
+
+Still with us? Good, lets get in a bit deeper...
+
+## Introduction
+
+In the following chapters, we will show how to use the API. But first, you need a very brief overview of the core elements of PHPCR. After reading this tutorial, you should browse through the API documentation to get an idea what operations you can do on each of those elements. See the conclusions for links if you want to have more background.
+
+* Node, Property: An object model for data structured similar to XML. A node is like the xml element, the property like the xml attribute. Properties are acquired from their nodes or directly from the session by their path. Nodes are acquired from parent nodes or from the session by their path. Both are Item, sharing the methods of that base interface. Names can be namespaced as in xml, and additionally may contain whitespaces or other not xml-legal characters.
+* Session: The authenticated connection to one workspace in the repository. Repository and workspace are immutable inside the Session. The session is the main interface to interact with the actual data. Sessions are acquired from a repository
+* Repository: Linking to one storage location with possibly many workspaces. Repositories are created with the help of the repository factory.
+* RepositoryFactory: Create repository instances for your implementation with implementation specific parameters.
+* Workspace: Provides general operations on the workspace of the Session it is acquired from.
+
+
+Not every implementation has to support all chapters of the specification. PHPCR is a modular standard and has a built-in way to discover the capabilities of your implementation.
+TODO: Add a section about capability testing to show how to write portable code.
+
+
+### Bootstrapping
+
+You will need to make sure your php classes are available. Usually this means activating an autoloader. For a standalone project, just use the file generated by composer at vendor/.composer/autoload.php
+PHPCR and Jackalope follow the PSR-0 standard. If you want your own autoloading, use a PSR-0 compatible autoloader and configure it to find the code folder.
+
+Once you have autoloading set up, bootstrap jackalope-jackrabbit like this:
+
+{% highlight php %}
+ 'http://localhost:8080/server');
+
+ // end of implementation specific configuration
+ // from here on, the whole code does not need to be changed when using different implementations
+
+ $factory = new $factoryclass();
+ $repository = $factory->getRepository($parameters);
+ if (null === $repository) {
+ var_dump($parameters);
+ die('There where missing parameters, the factory could not create a repository');
+ }
+
+ // the login parameters would typically live in a configuration file
+
+ $workspacename = 'default';
+ $user = 'admin';
+ $pass = 'admin';
+
+ // create credentials and log in to get a session
+ $credentials = new \PHPCR\SimpleCredentials($user, $pass);
+ try {
+ $session = $repository->login($credentials, $workspacename);
+ } catch(\PHPCR\LoginException $e) {
+ die('Invalid credentials: '.$e->getMessage());
+ } catch(\PHPCR\NoSuchWorkspaceException $e) {
+ die("No workspace $workspacename: ".$e->getMessage());
+ }
+
+ // if we get here, we have a session object that can be used to read and write the repository
+{% endhighlight %}
+
+
+### Get some data into the repository
+
+We will discuss the import feature in more detail later, but to have some data, we just import something here. Create an XML file test.xml like this:
+
+{% highlight xml %}
+
+
+
+
+
+
+
+
+
+
+
+{% endhighlight %}
+
+Now import this into the repository:
+
+{% highlight php %}
+ importXML('/', 'test.xml', \PHPCR\ImportUUIDBehaviorInterface::IMPORT_UUID_CREATE_NEW);
+ $session->save();
+{% endhighlight %}
+
+
+### Reading data and traversal
+
+You can wrap any code into try catch blocks. See the [API doc](http://phpcr.github.com/doc/html/index.html) for what exceptions to expect on which calls. With PHPCR being ported from Java, there is a lot of Exceptions defined.
+But as this is PHP, you don't have to catch them. As long as your content is as the code expects, it won't matter.
+
+{% highlight php %}
+ getNode('/data/node');
+ echo $node->getName(); // will be 'node'
+ echo $node->getPath(); // will be '/data/node'
+{% endhighlight %}
+
+
+#### Reading properties
+
+{% highlight php %}
+ getNode('/data/node');
+
+ // get the php value of a property (type automatically determined from stored information)
+ echo $node->getPropertyValue('title');
+
+ // get the Property object to operate on
+ $property = $node->getProperty('content');
+ echo 'Size of '.$property->getPath().' is '.$property->getLength();
+
+ // read a property that could be very long
+ $property = $node->getProperty('content');
+
+ // if it is binary convert into string
+ $data = $property->getString();
+ echo $data;
+
+ // get binary stream. could be more performant with binary property
+ $stream = $property->getBinary();
+ fpassthru($stream);
+ fclose($stream);
+
+ // the above in short if you just want to dump a file that is in a binary propery:
+ // fpassthru($node->getPropertyValue('binary-prop'));
+{% endhighlight %}
+
+Note: the backend stores the property types. When getting property values, they are returned
+with that type, unless you use one of the explicit PropertyInterface::getXX methods.
+For that case, type conversion is attempted and an exception thrown if this is not possible.
+
+See the API doc for a list of all supported types.
+
+{% highlight php %}
+ getPropertiesValues() as $name => $value) {
+ echo "$name: $value\n";
+ }
+ // get the properties of this node with a name starting with 't'
+ foreach ($node->getPropertiesValues("t*") as $name => $value) {
+ echo "$name: $value\n";
+ }
+{% endhighlight %}
+
+
+#### Traversing the hierarchy
+
+{% highlight php %}
+ getNode('/data/node');
+
+ // getting a node by path relative to the node
+ $othernode = $node->getNode('../sibling'); // /sibling
+
+ // get all child nodes. the $node is Iterable, the iterator being all children
+ $node = $session->getNode('/data/sibling');
+ foreach ($node as $name => $child) {
+ if ($child->hasProperties()) {
+ echo "$name has properties\n";
+ } else {
+ echo "$name does not have properties\n";
+ }
+ }
+
+ // get child nodes with the name starting with 'c'
+ foreach ($node->getNodes('c*') as $name => $child) {
+ echo "$name\n";
+ }
+
+ // get child nodes with the name starting with 'o' or ending with '2' or named 'yetanother'
+ foreach ($node->getNodes(array('o*', '*2', 'yetanother')) as $name => $child) {
+ echo "$name\n";
+ }
+
+ // get the parent node
+ $parent = $node->getParent(); // /
+
+ // build a breadcrumb of the node ancestry
+ $node = $session->getNode('/data/sibling/yetanother');
+ $i = 0;
+ $breadcrumb = array();
+ do {
+ $i++;
+ $parent = $node->getAncestor($i);
+ $breadcrumb[$parent->getPath()] = $parent->getName();
+ } while ($parent != $node);
+ var_dump($breadcrumb);
+{% endhighlight %}
+
+
+#### Node and property references
+
+Nodes can be referenced by unique id (if they are mix:referenceable) or by path. getValue returns the referenced node instance.
+Properties can only be referenced by path because they can not have a unique id.
+
+The test document we imported above does not contain the type information we
+need to show this example. Lets create a special one and load it into the repository with Session::importXML:
+
+{% highlight xml %}
+
+
+ nt:unstructured
+
+
+
+
+ nt:unstructured
+
+
+ mix:referenceable
+
+
+ 13543fc6-1abf-4708-bfcc-e49511754b40
+
+
+ Some value
+
+
+
+
+
+ nt:unstructured
+
+
+ 13543fc6-1abf-4708-bfcc-e49511754b40
+
+
+ ../target/someproperty
+
+
+
+
+{% endhighlight %}
+
+Now import the contents of that file instead of the other one. With this data, you can do this:
+
+{% highlight php %}
+ getNode('/idExample/source');
+ // will return you a node if the property is of type REFERENCE or WEAKREFERENCE
+ $othernode = $node->getPropertyValue('reference');
+
+ // force a node
+ $property = $node->getProperty('reference');
+ // will additionally try to resolve a PATH or NAME property and even work
+ // if the property is a STRING that happens to be a valid UUID or to
+ // denote an existing path
+ $othernode = $property->getNode();
+
+ // get a referenced property
+ $property = $node->getProperty('path');
+ $otherproperty = $property->getProperty();
+ echo $otherproperty->getName(); // someproperty
+ echo $otherproperty->getValue(); // Some value
+{% endhighlight %}
+
+
+#### Shareable nodes
+
+Optional feature, not yet implemented in Jackalope.
+
+Graph structure instead of a tree, nodes can have more than one parent.
+
+
+#### Same name siblings
+
+Optional feature, not fully tested in Jackalope.
+
+Nodes with the same parent can have the same name. They are distinguished by an index, as in xpath.
+
+
+### Query: Search the database
+
+{% highlight php %}
+ getWorkspace();
+ $queryManager = $workspace->getQueryManager();
+
+ $sql = "SELECT * FROM [nt:unstructured]
+ WHERE [nt:unstructured].[title] = 'Test'
+ ORDER BY [nt:unstructured].content";
+ $query = $queryManager->createQuery($sql, 'JCR-SQL2');
+ $query->setLimit(10); // limit number of results to be returned
+ $query->setOffset(1); // set an offset to skip first n results
+ $queryResult = $query->execute();
+
+ foreach ($queryResult->getNodes() as $path => $node) {
+ echo $node->getName();
+ }
+{% endhighlight %}
+
+
+#### Without building nodes
+
+There can be a little performance boost if you do not need to fetch the nodes
+but just want to access one value of each node.
+
+{% highlight php %}
+ $row) {
+ echo $path . ' scored ' . $row->getScore();
+
+ $row->getValue('a-value-you-know-exists');
+ }
+{% endhighlight %}
+
+Large search results can be dangerous for performance. See below for some
+performance tips.
+
+
+#### Using Query Object Model (QOM) for building complex queries
+
+PHPCR provides two languages to build complex queries. SQL2 and Query Object Model (QOM). While SQL2 expresses a query in a syntax similar to SQL, QOM expresses the query as a tree of PHPCR objects.
+
+In this section we will cover QOM. See the [JCR docs](http://phpcr.github.com/doc/html/index.html) for an exposition of both languages.
+
+You can access the QueryObjectModelFactory from the session:
+
+{% highlight php %}
+ getWorkspace()->getQueryManager()->getQOMFactory();
+{% endhighlight %}
+
+The QOM factory has a method to build a QOM query given four parameters, and [provides methods](http://phpcr.github.com/doc/html/phpcr/query/qom/queryobjectmodelfactoryinterface.html) to build these four parameters:
+
+ $queryObjectModel = $QOMFactory->createQuery(SourceInterface source, ConstraintInterface constraint, array orderings, array columns);
+
+`source` is made out of one or more selectors. Each selector selects a subset of nodes. Queries with more than one selector have joins. A query with two selectors will have a join, a query with three selectors will have two joins, and so on.
+
+`constraint` filters the set of node-tuples to be retrieved. Constraint may be combined in a tree of constraints to perform a more complex filtering. Examples of constraints are:
+
+* Absolute or relative paths: nodes descendant of a path, nodes children of a path, nodes reachable by a path.
+* Name of the node.
+* Value of a property.
+* Length of a property.
+* Existence of a property.
+* Full text search.
+
+`orderings` determine the order in which the filtered node-tuples will appear in the query results. The relative order of two node-tuples is determined by evaluating the specified orderings, in list order, until encountering an ordering for which one node-tuple precedes the other.
+
+`columns` are the columns to be included in the tabular view of query results. If no columns are specified, the columns available in the tabular view are implementation determined. In Jackalope include, for each selector, a column for each single-valued non-residual property of the selector's node type.
+
+The simplest case is to select all `[nt:unstructured]` nodes:
+
+{% highlight php %}
+ selector('a', '[nt:unstructured]');
+ $query = $qomFactory->createQuery($source, null, array(), array());
+ $queryResult = $query->execute();
+{% endhighlight %}
+
+
+#### The Query Builder: a fluent interface for QOM
+
+Sometimes you may prefer to build a query in several steps. For that reason, the phpcr-utils library provides a fluent wrapper for QOM: the QueryBuilder. It works with any PHPCR implementation.
+
+An example of query built with QueryBuilder:
+
+{% highlight php %}
+ from($qomFactory->selector('a', 'nt:unstructured'))
+ //some composed constraint
+ ->andWhere($qf->comparison($qf->propertyValue('a', 'title'),
+ QueryObjectModelConstantsInterface::JCR_OPERATOR_EQUAL_TO,
+ $qf->literal('Test')))
+ //orderings (descending by default)
+ ->orderBy($qf->propertyValue('a', 'content'))
+ //set an offset
+ ->setFirstResult(0)
+ //and the maximum number of node-tuples to retrieve
+ ->setMaxResults(25);
+ $result = $qb->execute();
+
+ foreach ($result->getNodes() as $node) {
+ echo $node->getName() . " has content: " . $node->getPropertyValue('content') . "\n";
+ }
+ //node has content: This is some test content
+ //sibling has content: This is another test content
+{% endhighlight %}
+
+
+### Writing data
+
+With PHPCR, you never use 'new'. The node works as a factory to create new nodes and properties. This has the nice side effect that you can not add a node where there is no parent.
+
+Everything you do on the Session, Node and Property objects is only visible locally in this session until you save the session.
+
+{% highlight php %}
+ //get the node from the session
+ $node = $session->getNode('/data/node');
+
+ // add a new node as child of $node
+ $newnode = $node->addNode('new node', 'nt:unstructured'); // until we have shown node types, just use nt:unstructured as type
+
+ // set a property on the new node
+ $newproperty = $newnode->setProperty('my property', 'my value');
+
+ // persist the changes permanently. now they also become visible in other sessions
+ $session->save();
+
+
+ // have a reference
+ $targetnode = $session->getNode('/data/sibling/yetanother');
+
+ // make sure the target node is referenceable.
+ $targetnode->addMixin('mix:referenceable');
+ // depending on the implementation, you might need to save the session at
+ // this point to have the identifier generated
+
+ // add a reference property to the node. because the property value is a
+ // Node, PHPCR will automatically detect that you want a reference
+ $node->setProperty('my reference', $targetnode);
+
+ $session->save();
+{% endhighlight %}
+
+#### Moving and deleting nodes
+
+{% highlight php %}
+ move('/data/sibling/yetanother', '/data/sibling/child1/yetanother');
+
+ // for this session, everything that was at /sibling/yetanother is now under /sibling/child1/yetanother
+ // i.e. /sibling/child1/yetanother/child
+ // once the session is saved, the move is persisted and visible in other sessions
+ // alternatively, you can immediatly move the node in the persistent storage
+
+ // rename node child2 to child2_new
+ $workspace = $session->getWorkspace();
+ $workspace->move('/data/sibling/child2', '/data/sibling/child2_new');
+
+ // copy a node and its children (only available on workspace, not inside session)
+ $workspace->copy('/data/sibling/yetanother', '/data/sibling/child1/yetanother');
+
+ // delete a node
+ $session->removeItem('/data/sibling/child1/yetanother');
+{% endhighlight %}
+
+
+#### Orderable child nodes
+
+While moving is about changing the parent of a node, ordering is used to set the
+position inside the child list. Preserving and altering order is an optional
+feature of PHPCR.
+
+The only method needed is Node::orderBefore
+
+{% highlight php %}
+ getNode('/data/node');
+
+ $node->addNode('first');
+ $node->addNode('second'); // new nodes are added to the end of the list
+ // order is: first, second
+
+ // ordering is done on the parent node. the first argument is the name of
+ // the child node to be reordered, the second the name of the node to moved
+ // node is placed before
+ $node->orderBefore('second', 'first');
+ // now the order is: second, first
+{% endhighlight %}
+
+
+### Versioning
+
+Versioning is used to track changes in nodes with the possibility to get back to older versions.
+
+A node with the mixin type mix:versionable or mix:simpleVersionable can be
+versioned. Versioned nodes have a version history, containing the root version
+and all versions created. Each version contains the meta data (previous
+versions, next versions and creation date) and provides a snapshot of the node
+at that point, called "frozen node".
+
+{% highlight php %}
+ getNode('/data/node');
+
+ $node->setProperty('foo', 'fafa');
+ // mark the node as versionable
+ $node->addMixin('mix:versionable');
+ $session->save();
+
+ // version operations are done through the VersionManager
+ $versionManager = $session->getWorkspace()->getVersionManager();
+
+ // put the versionable node into edit mode
+ $versionManager->checkout($node->getPath());
+ $node->setProperty('foo', 'bar'); // need a change to see something
+ $session->save(); // you can only create versions of saved nodes
+ // create a new version of the node with our changes
+ $version = $versionManager->checkin($node->getPath());
+ // Version extends the Node interface. The version is the node with additional functionality
+
+ // walk back the versions
+ $oldversion = $version->getLinearPredecessor();
+ // the version objects are just the meta data. call getFrozenNode on them
+ // to get a snapshot of the data when the version was created
+ echo $version->getName() . ': ' . $version->getFrozenNode()->getPropertyValue('foo') . "\n"; // 1.1: bar
+ echo $oldversion->getName() . ': ' . $oldversion->getFrozenNode()->getPropertyValue('foo'); // 1.0: fafa
+
+ // get the full version history
+ $history = $versionManager->getVersionHistory($node->getPath());
+ foreach ($history->getAllFrozenNodes() as $node) {
+ if ($node->hasProperty('foo')) {
+ // the root version does not have the property
+ echo $node->getPropertyValue('foo') . "\n";
+ }
+ }
+
+ // restore an old version
+ $node->setProperty('foo', 'different');
+ $versionManager->checkout($node->getPath());
+ $session->save(); // restoring is only possible if the session is clean
+ $current = $versionManager->getBaseVersion($node->getPath());
+ $versionManager->restore(true, $current);
+ echo $node->getPropertyValue('foo'); // fafa
+{% endhighlight %}
+
+
+### Locking
+
+In PHPCR, you can lock nodes to prevent concurrency issues. There is two basic types of locks:
+
+* Session based locks are only kept until your session ends and released automatically on logout.
+* If a lock is not session based, it is identified by a lock token and stays in place until it times out
+
+Note that jackalope currently only implements session based locks.
+
+{% highlight php %}
+ getNode('/data/sibling');
+ //the node has to be lockable
+ $node->addMixin('mix:lockable');
+ $session->save(); //node needs to be clean before locking
+
+ // get the lock manager
+ $workspace = $session->getWorkspace();
+ $lockManager = $workspace->getLockManager();
+ var_dump($lockManager->isLocked('/data/sibling')); // should be false
+ $lockManager->lock('/data/sibling', true, true); // lock child nodes as well, release when session closed
+ // now only this session may change the node //sibling and its descendants
+ var_dump($lockManager->isLocked('/data/sibling')); // should be true
+ var_dump($lockManager->isLocked('/data/sibling/child1')); // should be true because we locked deep
+
+ // getting the lock from LockManager is not yet implemented with jackalope-jackrabbit
+ $lock = $lockManager->getLock('/data/sibling');
+ var_dump($lock->isLockOwningSession()); // true, this is our lock, not somebody else's
+ var_dump($lock->getSecondsRemaining()); // PHP_INT_MAX because this lock has no timeout
+ var_dump($lock->isLive()); // true
+
+ $node = $lock->getNode(); // this gets us the node for /sibling
+ $node === $lockManager->getLock('/data/sibling')->getNode(); // getnode always returns the lock owning node
+
+ // now unlock the node again
+ $lockManager->unlock('/data/sibling'); // we could also let $session->logout() unlock when using session based lock
+ var_dump($lockManager->isLocked('/data/sibling')); // false
+ var_dump($lock->isLive()); // false
+{% endhighlight %}
+
+
+### Transactions
+
+The PHPCR API in itself uses some sort of 'transaction' model by only
+persisting changes on session save. If you need transactions over more than one
+save operation or including workspace operations that are dispatched immediatly,
+you can use transactions.
+
+Note that Jackalope does not support the full transactions.
+
+{% highlight php %}
+ getWorkspace();
+ $transactionManager = $workspace->getTransactionManager();
+ // start a transaction
+ $transactionManager->begin();
+ $session->removeNode('/data/sibling');
+ $session->getRootNode()->addNode('insideTransaction');
+ $session->save(); // wrote to the backend but not yet visible to other sessions
+ $workspace->move('/data/node', '/new'); // will only move the new node if session has been saved. still not visible to other sessions
+ $transactionManager->commit(); // now everything become persistent and visible to others
+
+ // you can abort a transaction
+ try {
+ ...
+ } catch(\Exception $e) {
+ if ($transactionManager->inTransaction()) {
+ $transactionManager->rollback();
+ }
+ ...
+ }
+{% endhighlight %}
+
+
+### Import and export data
+
+As promised, here are some more details on importing and exporting data. There
+are two formats:
+
+* The *document view* translates the data into a XML document with node names
+ as xml elements and properties as attributes and thus very readable. Type
+ information is lost, and illegal XML characters are encoded.
+* The *system view* is a more strict XML document defining the exact structure
+ of the repository with all type information. However, it is more verbose.
+
+As an analogy, think about an SQL dump file with SQL statements and the dump of
+an SQL table into a csv file. You can restore the data from both, but the SQL
+dump knows every detail about your field types and so on while the CSV just
+knows the data.
+
+When exporting, you tell explicitly to which format you want to export.
+
+{% highlight php %}
+ exportDocumentView(
+ '/data/sibling',
+ $file,
+ true, // skip binary properties to not have large files in the dump
+ false // recursivly output the child nodes as well
+ );
+
+ fclose($file);
+
+ $file = fopen('/tmp/system.xml', 'w+');
+ // export the tree at /foo/bar into a system view xml file
+ $session->exportSystemView(
+ '/data/sibling',
+ $file,
+ false, // do not skip binary properties
+ false
+ );
+
+ fclose($file);
+{% endhighlight %}
+
+Importing detects the format automatically. If the document is a valid JCR
+system view, it is interpreted according to that format, otherwise if it is a
+valid XML document it is imported as document.
+
+{% highlight php %}
+ getRootNode()->addNode('imported_data', 'nt:unstructured');
+ $session->importXML(
+ '/imported_data', // attach the imported data at this node
+ $filename,
+ ImportUUIDBehaviorInterface::IMPORT_UUID_CREATE_NEW
+ );
+{% endhighlight %}
+
+When importing nodes with a uuid, a couple of different behaviors can be used:
+
+* IMPORT_UUID_CREATE_NEW: Create new UUIDs for nodes that are imported, so you never get collisions.
+* IMPORT_UUID_COLLISION_THROW: Throw an exception if a node with the same UUID already exists.
+* IMPORT_UUID_COLLISION_REMOVE_EXISTING: Remove an existing node if an imported node has the same UUID.
+* IMPORT_UUID_COLLISION_REPLACE_EXISTING: Replace existing node with the imported node. This can lead to the imported data being put in various places.
+
+
+### Observation
+
+Observation enables an application to receive notifications of persistent changes to a workspace.
+JCR defines a general event model and specific APIs for asynchronous and journaled observation.
+A repository may support asynchronous observation, journaled observation or both.
+
+Note that Jackrabbit supports the full observation API but Jackalope currently only implements event journal reading.
+
+Write operations in Jackalope will generate journal entries as expected.
+
+{% highlight php %}
+ getWorkspace();
+ $observationManager = $workspace->getObservationManager();
+
+ // Get the unfiltered event journal and go through its content
+ $journal = $observationManager->getEventJournal();
+ $journal->skipTo(strtotime('-1 day')); // Skip all the events prior to yesterday
+ foreach ($journal as $event) {
+ // Do something with $event (it's a Jackalope\Observation\Event instance)
+ echo $event->getType() . ' - ' . $event->getPath();
+ }
+
+ // Filtering and using the journal as an iterator
+ // You can filter the event journal on several criteria, here we keep events for node and properties added
+ $journal = $observationManager->getEventJournal(EventInterface::NODE_ADDED | EventInterface::PROPERTY_ADDED);
+
+ while ($journal->valid()) {
+ $event = $journal->current();
+ // Do something with $event
+ $journal->next();
+ }
+{% endhighlight %}
+
+### Node Types
+
+PHPCR supports node types. Node types define what properties and children a node can or must have. The JCR specification explains exhaustivly what node types exist and what they are required to have or not: [JCR 2.0: 3.7.11 Standard Application Node Types](http://www.day.com/specs/jcr/2.0/3_Repository_Model.html#3.7.11%20Standard%20Application%20Node%20Types)
+
+In a nutshell:
+* nt:unstructured does not define any required properties but allows any property or child.
+* nt:file and nt:folder are built-in node types useful to map a file structure in the repository. (With jackalope-jackrabbit, files and folders are exposed over webdav)
+* for your own things, use nt:unstructured and PHPCR will behave like a NoSQL database
+* if you need to store additional properties or children on existing node types like files, note that while a node can have only one primary type, every node can have any mixin types. Define a mixin type declaring your additional properties, register it with PHPCR and addMixin it to the nodes that need it.
+
+You can define your own node types if you want the equivalent of a strictly defined database structure. See [JCR 2.0: 3.7 Node Types](http://www.day.com/specs/jcr/2.0/3_Repository_Model.html#3.7%20Node%20Types) and [JCR 2.0: 19 Node Type Management](http://www.day.com/specs/jcr/2.0/19_Node_Type_Management.html) / [PHPCR Node Type Namespace](http://phpcr.github.io/doc/html/index.html).
+
+
+## Performance considerations
+
+While PHPCR can perform reasonably well, you should be careful. You are working with an object model mapping interlinked data. Implementations are supposed to lazy load data only when necessary. But you should take care to only request what you actually need.
+
+The implementations will also use some sort of storage backend (Jackrabbit, (no)SQL database, ...). There might be a huge performance impact in configuring that storage backend optimally. Look into your implementation documentation if there are recommendations how to optimize storage.
+
+One thing *not* to worry about is requesting the same node with Session::getNode or Node::getNode/s several times. You always get the same object instance back without overhead.
+
+
+### Only request what you need
+
+Remember that you can filter nodes on Node::getNodes if you only need a list of specific nodes or all nodes in some namespace.
+
+The values of binary properties can potentially have a huge size and should only loaded when really needed. If you just need the size, you can get the property instance and do a $property->getSize() instead of filesize($node->getPropertyValue). Any decent implementation will not preload the binary stream when you access the property object.
+
+When getting the properties from a node, you can use Node::getPropertiesValues(filter, false). This allows the implementation to avoid instantiating Property objects for the property values (and saves you coding). The second boolean parameter tells wheter to dereference reference properties. If you do not need the referenced objects, pass false and you will get the UUID or path strings instead of node objects.(If you need one of them, you can still get it with Session::getNodeByIdentifier. But then the implementation will certainly not be able to optimize if you get several referenced nodes.)
+
+
+### But request in one call as much as possible of what you need
+
+If you need to get several nodes where you know the paths, use Session::getNodes with an array of those nodes to get all of them in one batch, saving round trip time to the storage backend.
+
+Also use Node::getNodes with a list of nodes rather than repeatedly calling Node::getNode.
+
+
+### Search
+
+TODO: intelligent filtering criteria to do as little in-memory operations to apply criteria.
+
+If you do not need the node objects but just some value, query for that value and use the result Row to avoid instantiating Node objects alltogether. If you need the Node objects, help PHPCR to optimize by using QueryResult::getNodes and iterating over the nodes instead of getting the rows, iterating over them and calling getNode on each row. (Actually, if you first do the getNodes(), you can then iterate over the rows and get the individual nodes and still use the special row methods as the implementation should have prefetched data on the getNodes.)
+
+
+## Conclusions
+
+We hope this tutorial helps to get you started. If you miss anything, have suggestions or questions, please contact us on jackalope-dev@googlegroups.com or #jackalope on irc.freenode.net
+
+### Further reading
+
+Browse through the [API documentation](http://phpcr.github.com/doc/html/index.html) to see what each of the core elements mentioned in the introduction can do.
+
+To fully understand the concepts behind the content repository API, we suggest reading [the Java content repository specification](http://www.day.com/specs/jcr/2.0/index.html) and
+then the [simplifications we did for PHP](https://github.com/phpcr/phpcr/blob/master/doc/JCR_TO_PHPCR.txt).
+
+
+### Not yet implemented
+
+A couple of other advanced functionalities are defined by the API. They are not yet implemented in any PHPCR implementation. This document will be updated once there is an implementation for them.
+
+* Permissions and capabilities
+* Access control management
+* Lifecycle managment
+* Retention and hold
+
diff --git a/implementations/index.md b/implementations/index.md
new file mode 100644
index 0000000..2b29d89
--- /dev/null
+++ b/implementations/index.md
@@ -0,0 +1,48 @@
+---
+layout: default
+title: Implementations
+---
+
+This page lists all known PHPCR implementations:
+
+{% for implementation in site.data.implementations|where:"stability","foonar" %}
+- **{{ implementation.stability }}**: [{{ implementation.name }}](#{{ implementation.name|downcase|replace: ' ', '_' }})
+{% endfor %}
+
+{% for implementation in site.data.implementations %}
+## {{ implementation.name }}
+
+{{ implementation.description }}
+
+- **Website**: [{{ implementation.website }}](implementation.website)
+- **Github**: [{{ implementation.github }}](implementation.github)
+- **Stability**: {{ implementation.stability }}
+
+{% if implementation.descriptors %}
+The following table lists the supported features as reported by the implementation (see the [JCR Spec](http://www.day.com/specs/jcr/2.0/24_Repository_Compliance.html) for more information):
+
+
+
+
+
Feature
+
Support
+
+
+
+ {% for descriptor in implementation.descriptors %}
+
+ {% assign value = descriptor[1] %}
+ {% if value == "true" %}
+ {% assign class = 'supported' %}
+ {% elsif descriptor[1] == 'false' %}
+ {% assign class = 'notsupported' %}
+ {% endif %}
+
+
- The PHP Content Repository is an adaption of the Java Content Repository (JCR) standard, an open API specification defined in JSR-283.
- The API defines how to handle hierarchical semi-structured data in a consistent way.
-
-
- The typical use case is content management systems.
- PHPCR combines the best out of document-oriented databases (weak structured data) and of XML databases (hierarchical trees). On top of that, it adds useful features like searching, versioning, access control and locking on top of it.
-
-
-
-
-
-
When to use PHPCR
-
-
For hierarchical navigation structures
-
For compound data that belongs together. i.e. a web page with attached files or translations
-
You need to version content
-
You want full text search
-
-
-
-
When not to use PHPCR
-
- PHPCR is targeted at semi structured content. For strictly structured content and when using aggregation queries, we recommend using relational databases.
- For example: A web shop where products are stored in PHPCR, orders are stored in a relational database.
-