Skip to content

Commit

Permalink
Added Sass support
Browse files Browse the repository at this point in the history
  • Loading branch information
lunetics committed May 24, 2012
1 parent 09ccf0b commit a531eeb
Show file tree
Hide file tree
Showing 14 changed files with 627 additions and 5 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,3 +1,4 @@
vendor/
Resources/bootstrap
Resources/bootstrap-sass
*.*~
3 changes: 3 additions & 0 deletions .gitmodules
@@ -1,3 +1,6 @@
[submodule "Resources/bootstrap"]
path = Resources/bootstrap
url = http://github.com/twitter/bootstrap.git
[submodule "Resources/bootstrap-sass"]
path = Resources/bootstrap-sass
url = http://github.com/thomas-mcdonald/bootstrap-sass.git
200 changes: 200 additions & 0 deletions Command/BootstrapSassInstallationCommand.php
@@ -0,0 +1,200 @@
<?php

namespace Mopa\Bundle\BootstrapBundle\Command;

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Mopa\Bridge\Composer\Adapter\ComposerAdapter;
use Mopa\Bridge\Composer\Util\ComposerPathFinder;


/**
* Command to check and create bootstrap symlink into MopaBootstrapBundle
*/
class BootstrapSassInstallationCommand extends ContainerAwareCommand
{
public static $mopaBootstrapBundleName = "mopa/bootstrap-bundle";
public static $twitterBootstrapName = "thomas-mcdonald/bootstrap-sass";

protected function configure()
{
$this
->setName('mopa:bootstrap-sass:install')
->setDescription("Check and if possible install symlink to bootstrap-sass")
->addArgument('pathToTwitterBootstrapSass', InputArgument::OPTIONAL, 'Where is thomas-mcdonald/bootstrap-sass located?')
->addArgument('pathToMopaBootstrapBundle', InputArgument::OPTIONAL, 'Where is MopaBootstrapBundle located?')
->addOption('force', 'f', InputOption::VALUE_NONE, 'Force rewrite of existing symlink if possible!')
->addOption('manual', 'm', InputOption::VALUE_NONE, 'If set please specify pathToTwitterBootstrapSass, and pathToMopaBootstrapBundle')
->setHelp(<<<EOT
The <info>mopa:bootstrap:install</info> command helps you checking and symlinking the thomas-mcdonald/bootstrap-sass library.
By default, the command uses composer to retrieve the paths of MopaBootstrapBundle and thomas-mcdonald/bootstrap-sass in your vendors.
If you want to control the paths yourself specify the paths manually:
php app/console mopa:bootstrap:install <comment>--manual</comment> <pathToTwitterBootstrapSass> <pathToMopaBootstrapBundle>
Defaults if installed by composer would be :
pathToTwitterBootstrapSass: ../../../../../../vendor/thomas-mcdonald/bootstrap-sass
pathToMopaBootstrapBundle: vendor/mopa/bootstrap-bundle/Mopa/BootstrapBundle/Resources/bootstrap
EOT
);
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$this->input = $input;
$this->output = $output;
if ($input->getOption('manual')) {
list($symlinkTarget, $symlinkName) = $this->getBootstrapPathsfromUser();
} elseif (false !== $composer = ComposerAdapter::getComposer($input, $output)) {
$cmanager = new ComposerPathFinder($composer);
$options = array(
'targetSuffix' => DIRECTORY_SEPARATOR . "Resources" . DIRECTORY_SEPARATOR . "bootstrap-sass",
'sourcePrefix' => '..' . DIRECTORY_SEPARATOR
);
list($symlinkTarget, $symlinkName) = $cmanager->getSymlinkFromComposer(
self::$mopaBootstrapBundleName,
self::$twitterBootstrapName,
$options
);
} else {
$this->output->writeln("<error>Could not find composer and manual option not secified!</error>");

return;
}

$this->output->write("Checking Symlink");
if (false === self::checkSymlink($symlinkTarget, $symlinkName, true)) {
$this->output->writeln(" ... <comment>not existing</comment>");
$this->output->writeln("Creating Symlink: " . $symlinkName);
$this->output->write("for Target: " . $symlinkTarget);
self::createSymlink($symlinkTarget, $symlinkName);
}
$this->output->writeln(" ... <info>OK</info>");
}

protected function getBootstrapPathsfromUser()
{
$symlinkTarget = $this->input->getArgument('pathToTwitterBootstrapSass');
$symlinkName = $this->input->getArgument('pathToMopaBootstrapBundle');
if (empty($symlinkName)) {
throw new \Exception("pathToMopaBootstrapBundle not specified");
} elseif (!is_dir(dirname($symlinkName))) {
throw new \Exception("pathToMopaBootstrapBundle: " . dirname($symlinkName) . " does not exist");
}
if (empty($symlinkTarget)) {
throw new \Exception("pathToTwitterBootstrapSass not specified");
} else {
if (substr($symlinkTarget, 0, 1) == "/") {
$this->output->writeln("<comment>Try avoiding absolute paths, for portability!</comment>");
if (!is_dir($symlinkTarget)) {
throw new \Exception("Target path " . $symlinkTarget . "is not a directory!");
}
} else {
$resolve =
$symlinkName . DIRECTORY_SEPARATOR .
".." . DIRECTORY_SEPARATOR .
$symlinkTarget;
$symlinkTarget = self::get_absolute_path($resolve);
}
if (!is_dir($symlinkTarget)) {
throw new \Exception("pathToTwitterBootstrapSass would resolve to: " . $symlinkTarget . "\n and this is not reachable from \npathToMopaBootstrapBundle: " . dirname($symlinkName));
}
}
$dialog = $this->getHelperSet()->get('dialog');
$text = <<<EOF
Creating the symlink: $symlinkName
Pointing to: $symlinkTarget
EOF
;
$this->output->writeln(array(
'',
$this->getHelperSet()->get('formatter')->formatBlock($text, $style = 'bg=blue;fg=white', true),
'',
));
if (!$dialog->askConfirmation($this->output, '<question>Should this link be created? (y/n)</question>', false)) {
exit;
}

return array($symlinkTarget, $symlinkName);
}

protected static function get_absolute_path($path)
{
$path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path);
$parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen');
$absolutes = array();
foreach ($parts as $part) {
if ('.' == $part) {
continue;
}
if ('..' == $part) {
array_pop($absolutes);
} else {
$absolutes[] = $part;
}
}

return implode(DIRECTORY_SEPARATOR, $absolutes);
}
/**
* Checks symlink
*
* @param string $symlinkTarget The Target
* @param string $symlinkName The Name
* @param boolean $forceSymlink Force to be a link or throw exception
*
* @throws \Exception
* @return boolean
*/
public static function checkSymlink($symlinkTarget, $symlinkName, $forceSymlink = false)
{
if (!$forceSymlink and file_exists($symlinkName) && !is_link($symlinkName)) {
$type = filetype($symlinkName);
if ($type != "link") {
throw new \Exception($symlinkName . " exists and is no link!");
}
} elseif (is_link($symlinkName)) {
$linkTarget = readlink($symlinkName);
if ($linkTarget != $symlinkTarget) {
if (!$forceSymlink) {
throw new \Exception("Symlink " . $symlinkName .
" Points to " . $linkTarget .
" instead of " . $symlinkTarget);
}
unlink($symlinkName);

return false;
} else {

return true;
}
}

return false;
}

/**
* Create the symlink
*
* @param string $symlinkTarget The Target
* @param string $symlinkName The Name
*
* @throws \Exception
*/
public static function createSymlink($symlinkTarget, $symlinkName)
{
if (false === @symlink($symlinkTarget, $symlinkName)) {
throw new \Exception("An error occured while creating symlink" . $symlinkName);
}
if (false === $target = readlink($symlinkName)) {
throw new \Exception("Symlink $symlinkName points to target $target");
}
}
}
26 changes: 25 additions & 1 deletion Composer/ScriptHandler.php
Expand Up @@ -9,6 +9,7 @@
use Composer\Script\Event;
use Mopa\Bridge\Composer\Util\ComposerPathFinder;
use Mopa\Bundle\BootstrapBundle\Command\BootstrapInstallationCommand;
use Mopa\Bundle\BootstrapBundle\Command\BootstrapSassInstallationCommand;

class ScriptHandler
{
Expand All @@ -29,10 +30,33 @@ public static function postInstallSymlinkTwitterBootstrap(Event $event)
);

$IO->write("Checking Symlink", FALSE);
if (false === BootstrapInstallationCommand::checkSymlink($symlinkTarget, $symlinkName, true)) {
if(false === BootstrapInstallationCommand::checkSymlink($symlinkTarget, $symlinkName, true)){
$IO->write("Creating Symlink: " . $symlinkName, FALSE);
BootstrapInstallationCommand::createSymlink($symlinkTarget, $symlinkName);
}
$IO->write(" ... <info>OK</info>");
}

public static function postInstallSymlinkTwitterBootstrapSass(Event $event)
{
$IO = $event->getIO();
$composer = $event->getComposer();
$cmanager = new ComposerPathFinder($composer);
$options = array(
'targetSuffix' => DIRECTORY_SEPARATOR . "Resources" . DIRECTORY_SEPARATOR . "bootstrap-sass",
'sourcePrefix' => '..' . DIRECTORY_SEPARATOR
);
list($symlinkTarget, $symlinkName) = $cmanager->getSymlinkFromComposer(
BootstrapSassInstallationCommand::$mopaBootstrapBundleName,
BootstrapSassInstallationCommand::$twitterBootstrapName,
$options
);

$IO->write("Checking Symlink", FALSE);
if(false === BootstrapSassInstallationCommand::checkSymlink($symlinkTarget, $symlinkName, true)){
$IO->write("Creating Symlink: " . $symlinkName, FALSE);
BootstrapSassInstallationCommand::createSymlink($symlinkTarget, $symlinkName);
}
$IO->write(" ... <info>OK</info>");
}
}
83 changes: 80 additions & 3 deletions Resources/doc/1-installation.md
Expand Up @@ -6,12 +6,18 @@ Prerequisites

### Less (recommended)

Less is not required, but is extremely helpful when using bootstrap2 variables, or mixins,
Less is not required, but is extremely helpful when using bootstrap variables, or mixins,
If you want to have a easier life, have a look into:
If you do not have less installed, currently you have several option, but please do NOT ask for help.

[Less Documentation](https://github.com/phiamo/MopaBootstrapBundle/blob/master/Resources/doc/less-installation.md)

### Sass (recommended)

Sass is not required, but is extremely helpful when using bootstrap variables, or mixins,
If you want to have a easier life, have a look into:
If you do not have sass installed, currently you have several option, but please do NOT ask for help.

Installation
------------

Expand Down Expand Up @@ -91,7 +97,7 @@ Installation
}
```

1.4. BootstrapBundle, twitters bootstrap and automatic symlinking
1.4.1 BootstrapBundle, twitters bootstrap and automatic symlinking

If you decided to let composer install twitters bootstrap, you might want to activate auto symlinking and checking, after composer update/install.
So add this to your existing scripts section in your composer json:
Expand Down Expand Up @@ -119,10 +125,81 @@ Installation
With these steps taken, bootstrap should be install into vendor/twitter/bootstrap/ and a symlink
been created into vendor/mopa/bootstrap-bundle/Mopa/BootstrapBundle/Resources/bootstrap.

1.4.2

For Sass Usage there is also a symlink command which can be added:

```json
{
"scripts": {
"post-install-cmd": [
"Mopa\\Bundle\\BootstrapBundle\\Composer\\ScriptHandler::postInstallSymlinkTwitterBootstrapSass"
],
"post-update-cmd": [
"Mopa\\Bundle\\BootstrapBundle\\Composer\\ScriptHandler::postInstallSymlinkTwitterBootstrapSass"
]
}
}
```

1.5. Include bootstrap manually or in another way:

For including bootstrap there are different solutions, why using this one?
have a look into [Including Bootstrap](https://github.com/phiamo/MopaBootstrapBundle/blob/master/Resources/doc/including-bootstrap.md)
have a look into [Including Bootstrap](https://github.com/phiamo/MopaBootstrapBundle/blob/master/Resources/doc/including-bootstrap.md)

1.6 Sass Installation

If you want to use Sass, check out the Documentation on Sass. Basically you just need to add one packe to composer.json:

```json
{
"require": {
"mopa/bootstrap-bundle": "dev-master",
"twitter/bootstrap": "master",
"knplabs/knp-paginator-bundle": "dev-master",
"knplabs/knp-menu-bundle": "dev-master",
"craue/formflow-bundle": "dev-master"
"thomas-mcdonald/bootstrap-sass": "dev-master"
},
"repositories": [
{
"type": "package",
"package": {
"version": "master", /* whatever version you want */
"name": "twitter/bootstrap",
"source": {
"url": "https://github.com/twitter/bootstrap.git",
"type": "git",
"reference": "master"
},
"dist": {
"url": "https://github.com/twitter/bootstrap/zipball/master",
"type": "zip"
}
}
},
{
"type":"package",
"package": {
"version":"dev-master",
"name":"thomas-mcdonald/bootstrap-sass",
"source": {
"url":"https://github.com/thomas-mcdonald/bootstrap-sass.git",
"type":"git",
"reference":"master"
},
"dist": {
"url":"https://github.com/thomas-mcdonald/bootstrap-sass/zipball/master",
"type":"zip"
}
}
}
]
}
```

You can also use the post-install cmd provided to setup the symlink for bootstrap-sass


2. Add this bundle to your app/AppKernel.php:

Expand Down
18 changes: 18 additions & 0 deletions Resources/doc/2-base-templates.md
Expand Up @@ -11,6 +11,13 @@ If you want to have a easier life, have a look into:

[Less Documentation](https://github.com/phiamo/MopaBootstrapBundle/blob/master/Resources/doc/less-installation.md)

### Less (recommended)

Sass is not required, but is extremely helpful when using bootstrap2 variables, or mixins,
If you want to have a easier life, have a look into:

[Sass Documentation](https://github.com/phiamo/MopaBootstrapBundle/blob/master/Resources/doc/sass-configuration.md)

Templates
---------

Expand Down Expand Up @@ -56,6 +63,17 @@ If you are using less just include the mopabootstrap.less as described in layout
{% endstylesheets %}
```

If you are using Sass just include the mopabootstrap.scss instead of the mopabootstrap.less

``` jinja
{% stylesheets filter='cssrewrite,?yui_css'
'@MopaBootstrapBundle/Resources/public/sass/mopabootstrapbundle.scss'
'@YourNiceBundle/Resources/public/sass/*'
%}
<link href="{{ asset_url }}" type="text/css" rel="stylesheet" />
{% endstylesheets %}
```

If you would like to use the css try this:

```bash
Expand Down

1 comment on commit a531eeb

@Primajin
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Please sign in to comment.