1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-21 05:51:41 +02:00

Initial commit to new repo (carried over from: https://github.com/ryancramerdesign/ProcessWire/tree/devns)

This commit is contained in:
Ryan Cramer
2016-09-02 14:55:17 -04:00
parent cfae5fc6f3
commit bac5b0de5d
1691 changed files with 279091 additions and 1 deletions

View File

@@ -0,0 +1,221 @@
Welcome to the Default/Basic Site Profile (Beginner Edition)
============================================================
This is a plain text document. If you are currently online with
internet access, you will find it much nicer to read an HTML
formatted version of this document located at:
http://processwire.com/docs/tutorials/default-site-profile/
Are you already somewhat familiar with ProcessWire and/or PHP? You
might also want to look into the Intermediate Edition of this profile.
Need multi-language support? The multi-language version of this
default site profile is a good place to start.
Both the intermediate and multi-language versions of this site
profile are available as installation options when installing
ProcessWire.
Introduction
============
Just getting started with ProcessWire and aren't totally clear on what
template files are? The good news is that template files aren't anything
other than regular HTML or PHP files, and you can use them however you
want!
If you know enough to create an HTML or PHP document, then you already
know how to use ProcessWire template files. The only difference is that
ProcessWire provides your template files with certain variables that
you may choose to use, or not use. Most notable is the $page variable,
which contains all the fields of text or other information contained
by the page being viewed.
For instance, $page->title contains the text contained in the Title
field of the current page, and $page->body contains the text for the
Body field of the current page. You can choose to output those wherever
you want. A really simple template file might look like a regular HTML
document except for where you want to output the dynamic portions (like
title and body). Here's an example:
<html>
<head>
<title><?= $page->title ?></title>
</head>
<body>
<h1><?= $page->title ?></h1>
<?= $page->body ?>
</body>
</html>
That's all that a template file is. Now when we're building something
for real, we like to save ourselves as much work as possible and avoid
writing the same HTML markup in multiple places. In order to do that
we'll usually isolate the repetitive markup into separate files or
functions so that we don't have to write it more than once. That's
not required of course, but it's a good strategy to save you time and
make it easier to maintain your site further down the road.
Template file strategies
========================
The two most popular strategies for template files are:
1. Direct Output is the simplest strategy and the one used by the
beginner edition of this site profile. While it doesn't scale as
well as other strategies, it is a very good point to start from.
If you've ever worked with WordPress templates, chances are you
already know how Direct Output works. Read more about the Direct
Output strategy:
http://processwire.com/to/direct-output/
2. Delayed Output is the strategy used by the intermediate edition
of this site profile. It is also quite simple but involves
populating content to placeholder variables rather than outputting
directly. As a result it may take a few more seconds to understand
than direct output, but the result is more scalable and
maintainable. Read more about Delayed Output here:
http://processwire.com/to/delayed-output/
How this Default Site Profile works (Beginner Edition)
======================================================
This Default Site Profile (beginner edition) uses the Direct Output
strategy. When a page is viewed on your site, here's what happens:
1. The initialization file is loaded (_init.php).
Here we use it just to define a shared function for navigation.
2. The template file is loaded (i.e. basic-page.php or another).
It outputs the content for the page.
Below are more details on exactly what takes place and in these two
steps outlined above:
1. The initialization file is loaded (_init.php)
---------------------------------------------
This step is completely optional with direct output, but we find
it handy to use this file to define our shared functions (if any).
In the case of this profile, we define a single renderNavTree()
function. It is useful to have this as a re-usable function since
we use it to generate markup for more than one place (specifically,
for sidebar navigation and for the sitemap). However, if you have
any confusion about this, ignore it for now and focus on #2 below
as an initialization file is completely optional.
2. The template file is loaded (i.e. basic-page.php or another)
------------------------------------------------------
Next, ProcessWire loads the template file used by the page being
viewed. For example, most pages here use basic-page.php.
The first thing that our template file does is include the HTML
header markup, which we've put in a file called _head.php:
include("./_head.php");
The above is simply a PHP function that says "include this file".
The leading "./" just means "from the current directory". We also
have an underscore "_" prepended to our filename here as a way
to identify this as an include file rather than a regular template
file. While completely optional, the underscore does also make
ProcessWire ignore it when looking for new template files, so you
may find it handy to use this convention in your own include files.
An alternate would be to use .inc as an extension rather than .php.
Have a look in the _head.php file now so you can see what's there.
It is basically half of an HTML file. Now have a look in _foot.php,
that's the other half. Notice that all the template files that
include _head.php at the beginning also include _foot.php at the
ending. This is to ensure there is a complete HTML document being
output.
To conclude, our template files (using direct output) are focused
on outputting what goes in-between the _head.php and _foot.php.
In our case, this is always a <div id='content'>...</div> and
optionally a <div id='sidebar'>...</div>. But for your own
template files you might choose to output something completely
different.
Files that make up this profile
===============================
Here is a summary of what is in each of the files in this directory.
We also recommend reviewing them in this order:
- _head.php
HTML header (top half of HTML document)
- _foot.php
HTML footer (bottom half of HTML document)
- basic-page.php
Template file outputting #content and #sidebar columns. This
template file is used by most pages in this small site.
- home.php
Template file used by homepage. Note that since the homepage uses
nearly the same layout as the other pages in the site, this
template file simply includes basic-page.php. No need two have
more than one template file with the same contents.
- sitemap.php
Outputs a sitemap of the entire site.
- search.php
Outputs results of site search queries.
- _init.php
Initialization file that we use to define a shared function for
generating navigation markup.
More template file resources
============================
- How do template files work?
https://processwire.com/api/templates/
Official documentation on template files.
- API variables
https://processwire.com/api/variables/
We mentioned $page above, but here are all the other API variables
your template file can make use of.
- API cheatsheet
http://cheatsheet.processwire.com/
Once you've got the basics down, this cheatsheet is invaluable in
describing all the properties and functions available to your
template files.
Tutorials that help with template files
=======================================
- Hello Worlds Tutoral, by Ryan Cramer
http://processwire.com/docs/tutorials/hello-worlds/
The Hello Worlds tutorial gently introduces ProcessWire and template
files, starting from a blank slate.
- "But what if I don't know how to code?", by Joss Sanglier
http://processwire.com/docs/tutorials/but-what-if-i-dont-know-how-to-code/
This particular series of tutorials will not only introduce you to
ProcessWire, but step by step, will give you those small bits of coding
knowledge that will get you going and open up this amazing world of a
Content Management Framework.
- Installing a CSS Framework, by Joss Sanglier
http://processwire.com/docs/tutorials/installing-a-css-framework/
A quick demonstration about how easy it is to use one of the many CSS
frameworks available to designers.
- How to structure your template files, by Ryan Cramer
http://processwire.com/docs/tutorials/how-to-structure-your-template-files/
This tutorial contrasts and compares the direct output and delayed
output strategies and more. It is a very good introduction to using
ProcessWire template files.

View File

@@ -0,0 +1,22 @@
</div><!--/#main-->
<!-- footer -->
<footer id='footer'>
<p>
Powered by <a href='http://processwire.com'>ProcessWire CMS</a> &nbsp; / &nbsp;
<?php
if($user->isLoggedin()) {
// if user is logged in, show a logout link
echo "<a href='{$config->urls->admin}login/logout/'>Logout ($user->name)</a>";
} else {
// if user not logged in, show a login link
echo "<a href='{$config->urls->admin}'>Admin Login</a>";
}
?>
</p>
</footer>
</body>
</html>

View File

@@ -0,0 +1,98 @@
<?php
/**
* Shared functions used by the beginner profile
*
* This file is included by the _init.php file, and is here just as an example.
* You could place these functions in the _init.php file if you prefer, but keeping
* them in this separate file is a better practice.
*
*/
/**
* Given a group of pages, render a simple <ul> navigation
*
* This is here to demonstrate an example of a simple shared function.
* Usage is completely optional.
*
* @param PageArray $items
*
*/
function renderNav(PageArray $items) {
if(!$items->count()) return;
echo "<ul class='nav'>";
// cycle through all the items
foreach($items as $item) {
// render markup for each navigation item as an <li>
if($item->id == wire('page')->id) {
// if current item is the same as the page being viewed, add a "current" class to it
echo "<li class='current'>";
} else {
// otherwise just a regular list item
echo "<li>";
}
// markup for the link
echo "<a href='$item->url'>$item->title</a> ";
// if the item has summary text, include that too
if($item->summary) echo "<div class='summary'>$item->summary</div>";
// close the list item
echo "</li>";
}
echo "</ul>";
}
/**
* Given a group of pages render a tree of navigation
*
* @param Page|PageArray $items Page to start the navigation tree from or pages to render
* @param int $maxDepth How many levels of navigation below current should it go?
*
*/
function renderNavTree($items, $maxDepth = 3) {
// if we've been given just one item, convert it to an array of items
if($items instanceof Page) $items = array($items);
// if there aren't any items to output, exit now
if(!count($items)) return;
// $out is where we store the markup we are creating in this function
// start our <ul> markup
echo "<ul class='nav nav-tree'>";
// cycle through all the items
foreach($items as $item) {
// markup for the list item...
// if current item is the same as the page being viewed, add a "current" class to it
if($item->id == wire('page')->id) {
echo "<li class='current'>";
} else {
echo "<li>";
}
// markup for the link
echo "<a href='$item->url'>$item->title</a>";
// if the item has children and we're allowed to output tree navigation (maxDepth)
// then call this same function again for the item's children
if($item->hasChildren() && $maxDepth) {
renderNavTree($item->children, $maxDepth-1);
}
// close the list item
echo "</li>";
}
// end our <ul> markup
echo "</ul>";
}

View File

@@ -0,0 +1,60 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title><?php echo $page->title; ?></title>
<meta name="description" content="<?php echo $page->summary; ?>" />
<link href='//fonts.googleapis.com/css?family=Lusitana:400,700|Quattrocento:400,700' rel='stylesheet' type='text/css' />
<link rel="stylesheet" type="text/css" href="<?php echo $config->urls->templates?>styles/main.css" />
</head>
<body class='has-sidebar'>
<!-- top navigation -->
<ul class='topnav'><?php
// top navigation consists of homepage and its visible children
$homepage = $pages->get('/');
$children = $homepage->children();
// make 'home' the first item in the navigation
$children->prepend($homepage);
// render an <li> for each top navigation item
foreach($children as $child) {
if($child->id == $page->rootParent->id) {
// this $child page is currently being viewed (or one of it's children/descendents)
// so we highlight it as the current page in the navigation
echo "<li class='current'><a href='$child->url'>$child->title</a></li>";
} else {
echo "<li><a href='$child->url'>$child->title</a></li>";
}
}
// output an "Edit" link if this page happens to be editable by the current user
if($page->editable()) {
echo "<li class='edit'><a href='$page->editUrl'>Edit</a></li>";
}
?></ul>
<!-- search form -->
<form class='search' action='<?php echo $pages->get('template=search')->url; ?>' method='get'>
<input type='text' name='q' placeholder='Search' value='' />
<button type='submit' name='submit'>Search</button>
</form>
<!-- breadcrumbs -->
<div class='breadcrumbs'><?php
// breadcrumbs are the current page's parents
foreach($page->parents() as $item) {
echo "<span><a href='$item->url'>$item->title</a></span> ";
}
// optionally output the current page as the last item
echo "<span>$page->title</span> ";
?></div>
<div id='main'>

View File

@@ -0,0 +1,15 @@
<?php
/**
* Initialization file for template files
*
* This file is automatically included as a result of $config->prependTemplateFile
* option specified in your /site/config.php.
*
* You can initialize anything you want to here. In the case of this beginner profile,
* we are using it just to include another file with shared functions.
*
*/
include_once("./_func.php"); // include our shared functions

View File

@@ -0,0 +1,15 @@
<?php namespace ProcessWire;
/**
* Admin template just loads the admin application controller,
* and admin is just an application built on top of ProcessWire.
*
* This demonstrates how you can use ProcessWire as a front-end
* to another application.
*
* Feel free to hook admin-specific functionality from this file,
* but remember to leave the require() statement below at the end.
*
*/
require($config->paths->adminTemplates . 'controller.php');

View File

@@ -0,0 +1,45 @@
<?php
include('./_head.php'); // include header markup ?>
<div id='content'><?php
// output 'headline' if available, otherwise 'title'
echo "<h1>" . $page->get('headline|title') . "</h1>";
// output bodycopy
echo $page->body;
// render navigation to child pages
renderNav($page->children);
// TIP: Notice that this <div id='content'> section is
// identical between home.php and basic-page.php. You may
// want to move this to a separate file, like _content.php
// and then include('./_content.php'); here instead, on both
// the home.php and basic-page.php template files. Then when
// you make yet more templates that need the same thing, you
// can simply include() it from them.
?></div><!-- end content -->
<div id='sidebar'><?php
// rootParent is the parent page closest to the homepage
// you can think of this as the "section" that the user is in
// so we'll assign it to a $section variable for clarity
$section = $page->rootParent;
// if there's more than 1 page in this section...
if($section->hasChildren > 1) {
// output sidebar navigation
// see _init.php for the renderNavTree function
renderNavTree($section);
}
// output sidebar text if the page has it
echo $page->sidebar;
?></div><!-- end sidebar -->
<?php include('./_foot.php'); // include footer markup ?>

View File

@@ -0,0 +1,11 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html>
<head>
<title>500 Internal Server Error</title>
</head>
<body>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error or misconfiguration and was unable to complete your request.</p>
<p>{message}</p>
</body>
</html>

View File

@@ -0,0 +1,21 @@
When a fatal error occurs, ProcessWire displays the message:
"Unable to complete this request due to an error."
The message is intentionally vague for security purposes.
Details will be logged to /site/assets/logs/errors.txt.
When present in this directory, the file 500.html will be
displayed instead of the generic error message above. Feel
free to modify this file to show whatever you would like.
Please note the following:
* 500.html is plain HTML and has no PHP or API access.
* You may enter the tag {message} and ProcessWire will
replace this with additional details when applicable.
When not applicable, it will make it blank.
* If you are logged in as an admin, ProcessWire will
give you a detailed error message rather than 500.html.

View File

@@ -0,0 +1,39 @@
<?php
include('./_head.php'); // include header markup ?>
<div id='content'><?php
// output 'headline' if available, otherwise 'title'
echo "<h1>" . $page->get('headline|title') . "</h1>";
// output bodycopy
echo $page->body;
// render navigation to child pages
renderNav($page->children);
?></div><!-- end content -->
<div id='sidebar'><?php
if(count($page->images)) {
// if the page has images on it, grab one of them randomly...
$image = $page->images->getRandom();
// resize it to 400 pixels wide
$image = $image->width(400);
// output the image at the top of the sidebar...
echo "<img src='$image->url' alt='$image->description' />";
}
// output sidebar text if the page has it
echo $page->sidebar;
?></div><!-- end sidebar -->
<?php include('./_foot.php'); // include footer markup ?>

View File

@@ -0,0 +1,3 @@
// Well hello there. Looks like we don't have any Javascript.
// Maybe you could help a friend out and put some in here?
// Or at least, when ready, this might be a good place for it.

View File

@@ -0,0 +1,69 @@
<?php
include("./_head.php"); ?>
<div id='content'>
<?php
// search.php template file
// See README.txt for more information.
// look for a GET variable named 'q' and sanitize it
$q = $sanitizer->text($input->get->q);
// did $q have anything in it?
if($q) {
// Sanitize for placement within a selector string. This is important for any
// values that you plan to bundle in a selector string like we are doing here.
$q = $sanitizer->selectorValue($q);
// Search the title and body fields for our query text.
// Limit the results to 50 pages.
$selector = "title|body~=$q, limit=50";
// If user has access to admin pages, lets exclude them from the search results.
// Note that 2 is the ID of the admin page, so this excludes all results that have
// that page as one of the parents/ancestors. This isn't necessary if the user
// doesn't have access to view admin pages. So it's not technically necessary to
// have this here, but we thought it might be a good way to introduce has_parent.
if($user->isLoggedin()) $selector .= ", has_parent!=2";
// Find pages that match the selector
$matches = $pages->find($selector);
// did we find any matches? ...
if($matches->count) {
// we found matches
echo "<h2>Found $matches->count page(s) matching your query:</h2>";
// output navigation for them (see TIP below)
echo "<ul class='nav'>";
foreach($matches as $match) {
echo "<li><a href='$match->url'>$match->title</a>";
echo "<div class='summary'>$match->summary</div></li>";
}
echo "</ul>";
// TIP: you could replace everything from the <ul class='nav'> above
// all the way to here, with just this: renderNav($matches);
} else {
// we didn't find any
echo "<h2>Sorry, no results were found.</h2>";
}
} else {
// no search terms provided
echo "<h2>Please enter a search term in the search box (upper right corner)</h2>";
}
?>
</div><!-- end content -->
<?php include("./_foot.php"); ?>

View File

@@ -0,0 +1,17 @@
<?php
include("./_head.php"); ?>
<div id='content'>
<?php
$maxDepth = 4;
renderNavTree($pages->get('/'), $maxDepth);
// see the _init.php for the renderNavTree function
?>
</div>
<?php include("./_foot.php"); ?>

View File

@@ -0,0 +1,293 @@
/**
* main.css
*
* 1. General HTML tags
* 2. Masthead area
* 3. Main content and sidebar
* 4. Footer
* 5. Media queries for responsive layout
*
*/
/*********************************************************************
* 1. General HTML tags
*
*/
* {
box-sizing: border-box;
}
body {
padding: 5%;
max-width: 1600px;
margin: 0 auto;
}
body, td, input[type=text], textarea {
font-family: 'Quattrocento', serif;
font-size: 105%;
line-height: 1.8em;
color: #444;
}
img {
max-width: 100%;
}
h2 {
font-weight: normal;
}
h3 {
border-top: 1px solid #eee;
padding-top: 1em;
color: #777;
}
a {
color: #333;
text-decoration: none;
border-bottom: 1px solid #ccc;
}
a:hover,
.nav a:hover {
color: #000;
border-color: #aaa;
}
blockquote {
margin-left: 0;
padding-left: 1.5em;
padding-right: 2em;
border-left: 4px solid #ddd;
font-style: italic;
color: #777;
}
pre, code {
background: #eee;
border: 1px solid #ddd;
}
pre {
font-size: 14px;
line-height: 1.4em;
padding: 1em;
border-left: 4px solid #ddd;
}
/*********************************************************************
* 2. Masthead area
*
*/
.topnav, .topnav li {
list-style: none;
padding: 0;
margin: 0;
}
.topnav li {
float: left;
margin-right: 1em;
margin-bottom: 1em;
}
.topnav a {
padding: 0.25em 0.5em;
text-decoration: none;
display: block;
background: #eee;
color: #333;
border: 1px solid #eee;
}
.topnav a:hover {
background: #ddd;
border-color: #ddd;
}
.topnav li.current a {
background: #ccc;
border-color: #ccc;
}
.topnav li.edit a {
background: none;
}
form.search {
float: right;
margin: 0;
width: 30%;
}
form.search input {
margin: 0;
padding: 0.25em 0.5em;
border: 1px solid #ccc;
width: 100%;
}
form.search button {
display: none;
}
.breadcrumbs {
clear: both;
padding-top: 1em;
}
.breadcrumbs span:after {
content: ">";
color: #999;
padding-left: 0.5em;
padding-right: 0.25em;
}
/*********************************************************************
* 3. Main content and sidebar
*
*/
#main {
border-top: 1px solid #eee;
padding-top: 1em;
margin-top: 1em;
clear: both;
}
#content {
width: 65%;
float: left;
padding-bottom: 2em;
}
#sidebar {
width: 35%;
padding-left: 5%;
float: left;
padding-bottom: 2em;
}
.nav {
margin-left: 0;
padding-left: 0;
list-style: none;
}
.nav .nav {
padding-left: 1.5em;
list-style: disc;
}
.nav li {
margin: 1em 0;
}
.nav-tree li {
margin-top: 0;
margin-bottom: 0;
}
.nav a {
font-weight: bold;
}
.nav-tree li a {
color: #777;
}
.nav .current > a {
color: #333;
}
.align_left {
/* for images placed in rich text editor */
float: left;
margin: 0 1em 0.5em 0;
position: relative;
top: 0.5em;
max-width: 50%;
}
.align_right {
/* for images placed in rich text editor */
float: right;
margin: 0 0 0.5em 1em;
max-width: 50%;
}
.align_center {
/* for images placed in rich text editor */
display: block;
margin: 1em auto;
position: relative;
top: 0.5em;
}
figure {
display: table;
width: 1px;
margin: 1em 0;
}
figure img {
display: table-row;
margin-bottom: 0.5em;
}
figure figcaption {
display: table-row;
font-size: smaller;
color: #777;
line-height: 1.4em;
}
/*********************************************************************
* 4. Footer
*
*/
#footer {
clear: both;
border-top: 1px solid #eee;
font-size: 80%;
}
/*********************************************************************
* 5. Media queries for responsive layout
*
*/
@media only screen and (max-width: 767px) {
/* mobile layout */
body, td, textarea {
font-size: 100%;
}
#content,
#sidebar {
float: none;
width: 100%;
padding: 0;
}
form.search {
float: none;
width: 100%;
}
#content {
width: 100%;
}
#sidebar {
border-top: 1px solid #eee;
padding-top: 1em;
}
.align_left, .align_right, .align_center {
display: block;
float: none;
margin: 1em auto;
max-width: 100%;
}
}
@media only screen and (min-width: 1200px) {
/* extra-wide desktop layout */
body, td, textarea {
font-size: 115%;
}
}