• Stars
    star
    122
  • Rank 292,031 (Top 6 %)
  • Language
    PHP
  • License
    MIT License
  • Created over 13 years ago
  • Updated almost 11 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Put your assets into the pipe and smoke them.

Pipe

Put your assets into the pipe and smoke them.

Pipe is an asset pipeline in the spirit of Sprockets. It's meant as the practical way for managing assets. It aims to provide a useful out of the box setup for managing assets and support for common preprocessor languages found in the web environment, like CoffeeScript or LESS.

What Pipe provides for you:

  • Out of the box support for Less and CoffeeScript
  • Integrated Dependency Managment.
  • Support for multiple asset load paths, which allows you to untie your application's libraries from your vendor libraries.
  • Tries to take the pain out of asset deployment, by being designed for dealing with cache busting and compression.

Build Status

Install

Get composer (if you haven't):

wget http://getcomposer.org/composer.phar

Then add this to a composer.json in your project's root:

{
    "require": {
        "chh/pipe": "*"
    }
}

Now install:

php composer.phar install

Getting Started

Environment

First you need an instance of Pipe\Environment. The environment holds your load paths, is used to retrieve assets and maps processors/engines to your assets.

The environment consists of multiple load paths. When retrieving an asset, it's looked up in every directory of the load paths. This way you can split your assets up in multiple directories, for example vendor_assets and assets.

To add some load paths, use the appendPath method. Paths can be prepended by the prependPath method. But use this carefully, because you can override assets this way.

<?php
use Pipe\Environment;

$env = new Environment;
$env->appendPath("assets");
$env->appendPath("vendor_assets");

Assets are retrieved by accessing an index of the environment instance, or by calling the find method.

The find method returns either null when no asset was found or an asset instance.

<?php

$asset = $env["js/application.js"];
# equal to:
$asset = $env->find("js/application.js");

To get the asset's processed body, use the getBody method.

<?php

echo $asset->getBody();

You can get the asset's last modified timestamp with the getLastModified method.

Dumping an Asset to a File

To dump an asset to a file, use the write method.

The write method takes an array of options:

  • dir (string): The directory is the prefix of the file. A hash of the asset's contents is automatically included in the resulting filename.
  • include_digest (bool): Should the SHA1 hash of the asset's contents be included in the filename?
  • compress (bool): Compresses the contents with GZIP and writes it with an .gz extension.

Enabling Compression

You can turn on compression by setting the js_compressor and css_compressor config keys, or by calling setJsCompressor or setCssCompressor on an Environment instance.

Supported Javascript Compressors:

  • uglify_js, uses the popular Uglify JS compressor built for NodeJS. Install with npm -g install uglify-js.
  • yuglify_js, Compressor built upon Uglify JS, and behaves like YUI compressor. Install with npm -g install yuglify.

Supported CSS Compressors:

  • yuglify_css, uses the Yuglify compressor's ability to compress CSS using CSSmin. Requires the yuglify NPM package.

Example:

<?php

$env = new Environment;
$env->appendPath("assets/stylesheets");
$env->appendPath("assets/vendor/stylesheets");
$env->appendPath("assets/javascripts");
$env->appendPath("assets/vendor/javascripts");

$env->setJsCompressor('yuglify_js');
$env->setCssCompressor('yuglify_css');

# Compressors are Bundle Processors. Bundle Processors are only run on Bundled Assets.
# Pass 'bundled' => true to get a Bundled Asset.
$asset = $env->find('application.js', ['bundled' => true]);

echo $asset->getBody();

Directives

Each file with content type application/javascript or text/css is processed by the DirectiveProcessor. The DirectiveProcessor parses the head of these files for special comments starting with an equals sign.

/* CSS
 *= require foo.css
 *= depend_on bar.css
 */

# CoffeeScript
#= require foo.coffee

// Javascript
//= require foo.js

The arguments for each directive are split by the Bourne Shell's rules. This means you have to quote arguments which contain spaces with either single or double quotes.

//= require "some name with spaces.js"

require

Usage:

require <path>

The require directive takes an asset path as argument, processes the asset and puts the dependency's contents before the asset's contents.

The path can also start with ./, which skips the load path for the path resolution and looks up the file in the same path as the current asset.

depend_on

Usage:

depend_on <path>

Defines that the path is a dependency of the current asset, but does not process anything. Assets defined this way get considered when the last modified time is calculated, but the contents get not prepended.

require_tree

Usage:

require_tree <path>

Requires all files found in the directory specified by path.

For example, if you have a directory for all individual widgets and a widget base prototype, then you could require_tree the widgets/ directory. This way every developer can just drop a file into the widgets/ directory without having to maintain a massive list of individual assets.

// index.js
//= require ./widget_base
//= require_tree ./widgets

Engines

Engines are used to process assets before they're dumped. Each engine is mapped to one or more file extension (e.g. CoffeeScript to .coffee). Each asset can be processed by one or more engines. Which engines are used on the asset and their order is determined by the asset's file extensions.

For example, to process an asset first by the PHP engine and then by the LESS compiler, give the asset the .less.php suffix.

Here's a list of the engines provided by default and their mapping to file extensions:

Engine Extensions Requirements
CoffeeScript .coffee coffee — install with npm install -g coffee-script
LESS .less lessc — install with npm install -g less
PHP .php, .phtml
Mustache .mustache Add phly/mustache package
Markdown .markdown, .md Add dflydev/markdown package
Twig .twig Add twig/twig package
TypeScript .ts tsc — install with npm install -g typescript

Under the hood, Pipe Engines are meta-template templates. Look at its README for more information on building your own engines.

To add an engine class to Pipe, use the environment's registerEngine method, which takes the engine's class name as first argument and an array of extensions as second argument.

Serving Assets dynamically.

Pipe includes a Pipe\Server which is able to serve assets dynamically via HTTP. The server is designed to be called in .php file, served via mod_php or FastCGI.

To use the dynamic asset server, you've to additionally require symfony/http-foundation. The require section of your composer.json should look like this:

{
    "require": {
        "chh/pipe": "*@dev",
        "symfony/http-foundation": "*"
    }
}

The server's constructor expects an environment as only argument. You can either construct the environment from scratch or use the Config class.

Put this in a file named assets.php:

<?php

use Pipe\Server,
    Pipe\Environment,
    Symfony\Component\HttpFoundation\Request;

$env = new Environment;
$env->appendPath("vendor_assets");
$env->appendPath("assets");

$server = new Server($env);
$server->dispatch(Request::createFromGlobals())
       ->send();

The server resolves all request URIs relative to the environment's load path. So to render the Javascript file js/index.js you would request the URI /assets.php/js/index.js.

The server also applies some conditional caching via Last-Modified and If-Not-Modified-Since HTTP headers. Should a change to a dependency not be instantly visible, try to make a hard refresh in your browser or clear your browser's cache.

Preparing Assets for Production Deployment

It's a good idea to compile assets in a way that they don't need the runtime support of Pipe. The Pipe\Manifest class is responsible for just that.

The Manifest is used to compile assets and writes a JSON encoded file which maps the logical paths (which the app knows anyway) to the paths including the digest (which the app can't know in advance).

To add a file to the manifest, call the manifest's compile method:

<?php

$env = new \Pipe\Environment;
$env->appendPath('assets/javascripts');

$manifest = new \Pipe\Manifest($env, 'build/assets/manifest.json');
$manifest->compile('index.js');

This creates the index-<SHA1 digest>.js file, and a manifest.json both in the build/assets directory.

This file looks a bit like this:

{
    "assets": {
        "index.js": "index-0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33.js"
    }
}

Then deploy everything located in build/assets, e.g. to some CDN or static file server.

An app running in a production environment could use the manifest like this, to create links to the assets:

<?php

# Better cache this, but omitted for brevity
$manifest = json_decode(file_get_contents('/path/to/manifest.json'), true);

# Path where the contents of "build/assets" are deployed.
# Could be a path to a CDN.
$prefix = "/assets";

printf('<script type="text/javascript" src="%s/%s"></script>', $prefix, $manifest['assets']['index.js']);

License

The MIT License

Copyright (c) 2012 Christoph Hochstrasser

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

More Repositories

1

phpenv

Thin Wrapper around rbenv for PHP version managment
Shell
571
star
2

heroku-buildpack-php

A more advanced PHP buildpack for Heroku, inspired by the Node.js buildpack
Shell
265
star
3

bob

Hi I'm Bob! I'm a tiny and messy build tool for PHP projects
PHP
104
star
4

sirel

Builder and Dumper for SQL Abstract Syntax Trees
PHP
37
star
5

jekyll-prismic

Add Prismic.io content to your Jekyll site
Ruby
31
star
6

cache-service-provider

A Cache Service Provider for Silex, using the doctrine/cache package
PHP
23
star
7

stack-honeypot

Inserts a trap for spam bots into responses.
PHP
22
star
8

jazz

Turns nested arrays into HTML.
PHP
21
star
9

eventemitter

A simple EventEmitter implementation in Go, using channels and Goroutines.
Go
20
star
10

optparse

Another Command Line Argument Parser
PHP
19
star
11

frozen-silex

Proof of concept, Converts your Silex Application to a static site.
PHP
19
star
12

kue

Generic interface to job queues for PHP projects.
PHP
18
star
13

Trek

Assists you on your journey through the mountainous areas of Database Schema Managment.
Shell
10
star
14

SimplePhar

[UNMAINTAINED] Compiles your Project to a PHAR (PHP Archive)
PHP
10
star
15

commander

Easy calling of system commands for PHP.
PHP
9
star
16

pod

a simple web server interface for PHP web apps, inspired by Rack.
PHP
9
star
17

itertools

Give iterator operations some love.
PHP
7
star
18

Underscore.php

[UNMAINTAINED] Collection of Utility functions in the spirit of Underscore.js
JavaScript
6
star
19

einhorn

A simple utility belt for using PHP with Einhorn.
PHP
5
star
20

httpfetch

A library for simple HTTP requests (using RingPHP)
PHP
5
star
21

pipe-silex

Pipe Extension for Silex
PHP
4
star
22

meta-template

Templating solution with adapters to many engines.
PHP
4
star
23

spark-http-utils

MOVED: Utilities for stacking and composing applications implementing HttpKernelInterface
PHP
4
star
24

phin

A simple HTTP Server which connects to applications through a Rack-like Protocol
PHP
4
star
25

cheatsheets

Various cheatsheets for stuff I do
4
star
26

Simple-CMS

[UNMAINTAINED] A very simple CMS, just put text files in the pages directory and you're off to go! (no Database required, depends on Zend Framework and Spark Web Framework)
PHP
4
star
27

eventor

A sane interface to PHP's libevent extension.
PHP
3
star
28

onestroke-icons

[UNMAINTAINED] A very simple icon pack primarly for web applications
Shell
3
star
29

livesyncd

Simple, Fast, One-Way, Sync Daemon, using SFTP — similar to the "Auto-Deployment" feature present in most IDEs
Go
3
star
30

Spark2

[UNMAINTAINED] Eine DSL für PHP Web-Applikationen
PHP
2
star
31

php-styleguide

PHP Styleguide for contributions to my projects.
2
star
32

shellwords

A lame port of Ruby's Shellwords.rb
PHP
2
star
33

amadeus

A simple generator for truly static Composer repositories. Consider this a Proof of Concept.
PHP
2
star
34

Spark-Web-Framework

[DEAD] A simple Framework extending the Zend Framework.
PHP
2
star
35

CHH.github.io

Personal blog and website
HTML
2
star
36

ooio

Object oriented IO for PHP.
PHP
2
star
37

funk

Minimal functional programming library for PHP
PHP
2
star
38

weblife1auth

[UNMAINTAINED] Weblife1Auth provides an adapter for Zend_Auth for log on to the Weblife1 API
PHP
2
star
39

superfeedr-ping

Simple service which pings Superfeedr when a Github web hook was triggered
PHP
2
star
40

Concatenator.php

[UNMAINTAINED] A simple port of Sprockets (https://github.com/sstephenson/sprockets) to PHP
PHP
2
star
41

git-einsatz-ooe

Vue
1
star
42

yuribike

JavaScript
1
star
43

gridsome-source-rss

RSS source for gridsome
JavaScript
1
star
44

Project-Template

This is the Template for all my Projects. There are many like it, but this one is mine.
PHP
1
star
45

fileutils

Some file related utility functions and variations of internal functions which take callbacks.
PHP
1
star
46

fswatch

Run a command everytime a file changes
Go
1
star
47

dotfiles

My dotfiles.
Shell
1
star
48

netchan

Yields socket connections on a channel
Go
1
star
49

Szene1Api

[UNMAINTAINED] Sehr einfache Bibliothek zum Zugriff auf das SZENE1 API für PHP 5.3+
PHP
1
star
50

Spark2_Quickstart

[UNMAINTAINED] Ein Startpaket für neue Spark2 Applikationen
PHP
1
star