├── .gitignore
├── Command
├── ClearCommand.php
└── CompilerCommand.php
├── DependencyInjection
├── Configuration.php
└── RuianTwitterBootstrapExtension.php
├── Exception
└── TwitterBootstrapVersionException.php
├── Features
├── Command.feature
└── Context
│ └── FeatureContext.php
├── README.md
├── Resources
├── config
│ ├── routing.yml
│ └── services.yml
├── public
│ ├── css
│ │ └── .keep
│ ├── img
│ │ └── .keep
│ └── js
│ │ └── .keep
└── views
│ ├── Alert
│ ├── bootstrap_v1.html.twig
│ └── bootstrap_v2.html.twig
│ └── Form
│ ├── bootstrap_v1.html.twig
│ └── bootstrap_v2.html.twig
├── RuianTwitterBootstrapBundle.php
└── composer.json
/.gitignore:
--------------------------------------------------------------------------------
1 | Resources/public/js
2 | Resources/public/css
3 | Resources/public/img
4 |
--------------------------------------------------------------------------------
/Command/ClearCommand.php:
--------------------------------------------------------------------------------
1 | versions = array(
20 | 'v1',
21 | 'v2'
22 | );
23 | }
24 |
25 | protected function configure()
26 | {
27 | $this
28 | ->setName('twitter-bootstrap:clear')
29 | ->setDescription('Delete any css and js in RuianTwitterBootstrapBundle Resources')
30 | ;
31 | }
32 |
33 | protected function execute(InputInterface $input, OutputInterface $output)
34 | {
35 | $finder = new Finder();
36 | $finder->files()->in(__DIR__ . '/../Resources/public/')->name('/(js$)|(css$)/')->sortByName();
37 |
38 | foreach ($finder->files() as $file) {
39 | unlink($file->getRealPath());
40 | $output->writeln('Delete '. $file->getFilename() .'');
41 | }
42 | $output->writeln('Success every files had been removed');
43 | }
44 | }
--------------------------------------------------------------------------------
/Command/CompilerCommand.php:
--------------------------------------------------------------------------------
1 | versions = array(
21 | 'v1',
22 | 'v2'
23 | );
24 | }
25 |
26 | protected function configure()
27 | {
28 | $this
29 | ->setName('twitter-bootstrap:compile')
30 | ->setDescription('Compile a version of twitter-bootstrap and paste it into RuianTwitterBundle public folder')
31 | ->addArgument('version', InputArgument::OPTIONAL, 'Main version v1 or v2', 'v1')
32 | ;
33 | }
34 |
35 | protected function execute(InputInterface $input, OutputInterface $output)
36 | {
37 | $version = $input->getArgument('version');
38 |
39 | if (false === in_array($version, $this->versions)) {
40 | throw new TwitterBootstrapVersionException("Version you have selected is not supported, or inexistant. Please choose one of these versions " . implode(' or ', $this->versions));
41 | }
42 |
43 | if (true === $this->writeCss($version, $output)) {
44 | $output->writeln('Success, bootstrap'.$version.'.css has been written in /Ruian/TwitterBootstrapBundle/Resources/public/css/bootstrap'.$version.'.css');
45 | }
46 |
47 | if (true === $this->writeJs($version, $output)) {
48 | $output->writeln('Success, bootstrap'.$version.'.js has been written in /Ruian/TwitterBootstrapBundle/Resources/public/js/bootstrap'.$version.'.js');
49 | }
50 |
51 | if (true === $this->copyImages($version, $output)) {
52 | $output->writeln('Success, bootstrap'.$version.' images have been copied to /Ruian/TwitterBootstrapBundle/Resources/public/img');
53 | }
54 | }
55 |
56 | protected function writeCss($version, $output)
57 | {
58 | if (!is_dir(__DIR__ . '/../Resources/public/css/')) {
59 | mkdir(__DIR__ . '/../Resources/public/css/', 0777, true);
60 | }
61 |
62 | if ('v1' === $version) {
63 | $in = __DIR__ . '/../../../../twitter/bootstrap/'.$version.'/lib/bootstrap.less';
64 | $out = __DIR__ . '/../Resources/public/css/bootstrap' . $version . '.css';
65 |
66 | lessc::ccompile($in, $out);
67 |
68 | $output->writeln('Writing bootstrap'.$version.'.css from bootstrap.less');
69 | $output->writeln('You can add bundles/ruiantwitterbootstrap/css/bootstrap'.$version.'.css to your layout');
70 | }
71 |
72 | if ('v2' === $version) {
73 | $in = __DIR__ . '/../../../../twitter/bootstrap/'.$version.'/less/bootstrap.less';
74 | $out = __DIR__ . '/../Resources/public/css/bootstrap' . $version . '.css';
75 |
76 | lessc::ccompile($in, $out);
77 |
78 | $output->writeln('Writing bootstrap'.$version.'.css from bootstrap.less');
79 | $output->writeln('You can add bundles/ruiantwitterbootstrap/css/bootstrap'.$version.'.css to your layout');
80 |
81 | $in = __DIR__ . '/../../../../twitter/bootstrap/'.$version.'/less/responsive.less';
82 | $out = __DIR__ . '/../Resources/public/css/bootstrap' . $version . '-responsive.css';
83 |
84 | lessc::ccompile($in, $out);
85 |
86 | $output->writeln('Writing bootstrap'.$version.'-responsive.css from responsive.less');
87 | $output->writeln('You can add bundles/ruiantwitterbootstrap/css/bootstrap'.$version.'-responsive.css to your layout');
88 | }
89 |
90 | return true;
91 | }
92 |
93 | protected function copyImages($version, $output) {
94 | //no images to copy for 1.x bootstrap
95 |
96 | if ('v2' === $version) {
97 | if (!is_dir(__DIR__ . '/../Resources/public/img/')) {
98 | mkdir(__DIR__ . '/../Resources/public/img/', 0777, true);
99 | }
100 |
101 | foreach (glob(__DIR__ . '/../../../../twitter/bootstrap/'.$version.'/img/*') as $image) {
102 | copy($image, __DIR__ . '/../Resources/public/img/' . basename($image));
103 | }
104 | }
105 |
106 | return true;
107 | }
108 |
109 | protected function writeJs($version, $output)
110 | {
111 | $jsDir = __DIR__ . '/../../../../twitter/bootstrap/'.$version.'/js/';
112 |
113 | if (!is_dir(__DIR__ . '/../Resources/public/js/')) {
114 | mkdir(__DIR__ . '/../Resources/public/js/', 0777, true);
115 | }
116 |
117 | //here we use finder only to add some new files if bootstrap adds them
118 | //default bootstrap files, order is important
119 | $files = array('bootstrap-transition.js',
120 | 'bootstrap-alert.js',
121 | 'bootstrap-button.js',
122 | 'bootstrap-carousel.js',
123 | 'bootstrap-collapse.js',
124 | 'bootstrap-dropdown.js',
125 | 'bootstrap-modal.js',
126 | 'bootstrap-tooltip.js',
127 | 'bootstrap-popover.js',
128 | 'bootstrap-scrollspy.js',
129 | 'bootstrap-tab.js',
130 | 'bootstrap-typeahead.js');
131 |
132 | $finder = new Finder();
133 | $finder->depth('== 0');
134 | $finder->files()->in($jsDir)->name('*.js');
135 |
136 | foreach ($finder as $file) {
137 | $baseFile = basename($file);
138 | if (!in_array($baseFile, $files)) {
139 | $output->writeln(sprintf('Found NEW file "%s", bootstrap has new javascripts?', $baseFile));
140 | $files[] = $baseFile;
141 | }
142 | }
143 |
144 | $bootstrapjs = null;
145 |
146 | foreach ($files as $file) {
147 | $bootstrapjs .= file_get_contents(realpath($jsDir . $file));
148 | $output->writeln('Adding '.$file.'');
149 | }
150 |
151 | file_put_contents(__DIR__ . '/../Resources/public/js/bootstrap'.$version.'.js', $bootstrapjs);
152 |
153 | $output->writeln('Writing bootstrap'.$version.'.js');
154 | $output->writeln('You can add bundles/ruiantwitterbootstrap/js/bootstrap'.$version.'.js to your layout');
155 |
156 | return true;
157 | }
158 | }
--------------------------------------------------------------------------------
/DependencyInjection/Configuration.php:
--------------------------------------------------------------------------------
1 | root('ruian_twitter_bootstrap');
22 |
23 | // Here you should define the parameters that are allowed to
24 | // configure your bundle. See the documentation linked above for
25 | // more information on that topic.
26 |
27 | return $treeBuilder;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/DependencyInjection/RuianTwitterBootstrapExtension.php:
--------------------------------------------------------------------------------
1 | processConfiguration($configuration, $configs);
24 |
25 | $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
26 | $loader->load('services.yml');
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Exception/TwitterBootstrapVersionException.php:
--------------------------------------------------------------------------------
1 | application = new Application($kernel);
39 | $this->application->add(new CompilerCommand());
40 | $this->application->add(new ClearCommand());
41 | // add other commands if needed
42 | }
43 |
44 | /**
45 | * @When /^I run "([^"]*)" command$/
46 | */
47 | public function iRunCommand($cmd_line)
48 | {
49 | $input = new StringInput($cmd_line);
50 | $command = $this->application->find($input->getFirstArgument('command'));
51 | $input = new StringInput($cmd_line, $command->getDefinition());
52 | $this->output = new StreamOutput(fopen('php://memory', 'w', false));
53 | $command->run($input, $this->output);
54 | }
55 |
56 | /**
57 | * @Then /^I should see$/
58 | */
59 | public function iShouldSee(PyStringNode $string)
60 | {
61 | rewind($this->output->getStream());
62 | $display = stream_get_contents($this->output->getStream());
63 | assertSame($string->getRaw(), $display);
64 | }
65 |
66 | /**
67 | * @Then /^I should get a file "([^"]*)"$/
68 | */
69 | public function iShouldGetAFile($filename)
70 | {
71 | $assert = false;
72 | $finder = new Finder();
73 | $finder->files()->in(__DIR__ . '/../../Resources/public/')->name('/(css$)|(js$)/');
74 |
75 | foreach ($finder->files() as $file) {
76 | if ($filename === $file->getFilename()) {
77 | $assert = true;
78 | }
79 | }
80 |
81 | assertTrue($assert);
82 | }
83 |
84 | /**
85 | * @Then /^I should get no file$/
86 | */
87 | public function iShouldGetNoFile()
88 | {
89 | $finder = new Finder();
90 | $finder->files()->in(__DIR__ . '/../../Resources/public/')->name('/(css$)|(js$)/');
91 |
92 | $assert = true;
93 | foreach ($finder->files() as $key => $value) {
94 | $assert = false;
95 | break;
96 | }
97 |
98 | assertTrue($assert);
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | TwitterBootstrapBundle
2 | ======================
3 |
4 | #WARNING
5 | If you use a symfony 2.0.x version please use the correct branch of this bundle (2.0.x in that case)
6 |
7 | #How to install ?
8 |
9 | ##Add theses lines into your deps
10 |
11 | ```
12 | [RuianTwitterBootstrapBundle]
13 | git=git://github.com/ruian/TwitterBootstrapBundle.git
14 | version=origin/master
15 | target=/bundles/Ruian/TwitterBootstrapBundle
16 |
17 | [TwitterBootstrap1]
18 | git=git://github.com/twitter/bootstrap.git
19 | target=/twitter/bootstrap/v1/
20 | version=v1.4.0
21 |
22 | [TwitterBootstrap2]
23 | git=git://github.com/twitter/bootstrap.git
24 | target=/twitter/bootstrap/v2/
25 | version=v2.0.0
26 |
27 | [lessphp]
28 | git=git://github.com/leafo/lessphp.git
29 | target=/lessphp/
30 | version=origin/master
31 | ```
32 |
33 | ##Add autoloading
34 |
35 | ```php
36 | #app/autoload.php
37 | registerNamespaces(array(
39 | #...
40 | 'Ruian' => __DIR__.'/../vendor/bundles',
41 | ));
42 |
43 | #some code...
44 |
45 | // Add support for lessc
46 | require __DIR__.'/../vendor/lessphp/lessc.inc.php';
47 |
48 | ```
49 |
50 | ##Register this bundle
51 |
52 | ```php
53 | #app/AppKernel.php
54 |
85 |
86 |
87 | Twitter Bootstrap
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | ```
97 |
98 | ##Use bootstrap form style
99 | Replace VERSION by the supported version you want, v1 or v2
100 |
101 | ```
102 | {% form_theme form_view 'RuianTwitterBootstrapBundle:Form:bootstrap_VERSION.html.twig' %}
103 | ```
104 |
105 |
106 | ##Example
107 |
108 | ```html
109 | #Ruian/DemoBundle/Resources/view/new.html.twig
110 |
111 |
112 |
113 | New article
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 | {% include 'RuianTwitterBootstrapBundle:Alert:bootstrap_v2.html.twig' %}
123 |
124 | {% form_theme form_view 'RuianTwitterBootstrapBundle:Form:bootstrap_v2.html.twig' %}
125 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 | ```
139 |
140 | ```php
141 | #Ruian/DemoBundle/Controller/ArticleController.php
142 | createForm(new ArticleType(), $entity);
156 |
157 | $request = $this->get('request');
158 | if ('POST' === $request->getMethod()) {
159 | $form->bindRequest($request);
160 | if (true === $form->isValid()) {
161 | $em = $this->get('doctrine.orm.default_entity_manager');
162 | $em->persist($entity);
163 | $em->flush();
164 |
165 | $this->setFlashSuccess('Congratulation, your article has been saved.');
166 | return $this->redirect($this->generateUrl('RuianDemoBundle_new'));
167 | } else {
168 | $this->setFlashError('Warning, your article can\'t be saved due to some errors.');
169 | }
170 | }
171 |
172 | return $this->render('RuianDemoBundle:Article:new.html.twig', array(
173 | 'form_view' => $form->createView(),
174 | ));
175 | }
176 |
177 | protected function setFlashSuccess($message)
178 | {
179 | $this->get('session')->setFlash('alert-success', $message);
180 | }
181 |
182 | protected function setFlashError($message)
183 | {
184 | $this->get('session')->setFlash('alert-error', $message);
185 | }
186 |
187 | # some code ...
188 | }
189 |
190 | ```
--------------------------------------------------------------------------------
/Resources/config/routing.yml:
--------------------------------------------------------------------------------
1 | RuianTwitterBootstrapBundle_homepage:
2 | pattern: /hello/{name}
3 | defaults: { _controller: RuianTwitterBootstrapBundle:Default:index }
4 |
--------------------------------------------------------------------------------
/Resources/config/services.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | # ruian_twitter_bootstrap.example.class: Ruian\TwitterBootstrapBundle\Example
3 |
4 | services:
5 | # ruian_twitter_bootstrap.example:
6 | # class: %ruian_twitter_bootstrap.example.class%
7 | # arguments: [@service_id, "plain_value", %parameter%]
8 |
--------------------------------------------------------------------------------
/Resources/public/css/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ruian/TwitterBootstrapBundle/1594b84da7450f5740eb225bf3bde0e6792a0800/Resources/public/css/.keep
--------------------------------------------------------------------------------
/Resources/public/img/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ruian/TwitterBootstrapBundle/1594b84da7450f5740eb225bf3bde0e6792a0800/Resources/public/img/.keep
--------------------------------------------------------------------------------
/Resources/public/js/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ruian/TwitterBootstrapBundle/1594b84da7450f5740eb225bf3bde0e6792a0800/Resources/public/js/.keep
--------------------------------------------------------------------------------
/Resources/views/Alert/bootstrap_v1.html.twig:
--------------------------------------------------------------------------------
1 | {% if app.session.hasFlash('alert-success') %}
2 | {% set message = app.session.getFlash('alert-success') %}
3 | {% set type = 'success' %}
4 | {% endif %}
5 |
6 | {% if app.session.hasFlash('alert-error') %}
7 | {% set message = app.session.getFlash('alert-error') %}
8 | {% set type = 'error' %}
9 | {% endif %}
10 |
11 | {% if app.session.hasFlash('alert-warning') %}
12 | {% set message = app.session.getFlash('alert-warning') %}
13 | {% set type = 'warning' %}
14 | {% endif %}
15 |
16 | {% if app.session.hasFlash('alert-info') %}
17 | {% set message = app.session.getFlash('alert-info') %}
18 | {% set type = 'info' %}
19 | {% endif %}
20 |
21 | {% if type is defined %}
22 | {# --> Start bootstrap_alert block #}
23 | {% block bootstrap_alert %}
24 |
25 |
×
26 | {{ message }}
27 |
28 | {% endblock bootstrap_alert %}
29 | {# <-- End bootstrap_alert block #}
30 | {% endif %}
--------------------------------------------------------------------------------
/Resources/views/Alert/bootstrap_v2.html.twig:
--------------------------------------------------------------------------------
1 | {% if app.session.hasFlash('alert-success') %}
2 | {% set title = 'Success' %}
3 | {% set message = app.session.getFlash('alert-success') %}
4 | {% set type = 'success' %}
5 | {% endif %}
6 |
7 | {% if app.session.hasFlash('alert-error') %}
8 | {% set title = 'Error' %}
9 | {% set message = app.session.getFlash('alert-error') %}
10 | {% set type = 'error' %}
11 | {% endif %}
12 |
13 | {% if app.session.hasFlash('alert-warning') %}
14 | {% set title = 'Warning' %}
15 | {% set message = app.session.getFlash('alert-warning') %}
16 | {% set type = 'warning' %}
17 | {% endif %}
18 |
19 | {% if app.session.hasFlash('alert-info') %}
20 | {% set title = 'Info' %}
21 | {% set message = app.session.getFlash('alert-info') %}
22 | {% set type = 'info' %}
23 | {% endif %}
24 |
25 | {% if type is defined %}
26 | {# --> Start bootstrap_alert block #}
27 | {% block bootstrap_alert %}
28 |
29 |
×
30 |
{{ title }}
31 | {{ message }}
32 |
33 | {% endblock bootstrap_alert %}
34 | {# <-- End bootstrap_alert block #}
35 | {% endif %}
--------------------------------------------------------------------------------
/Resources/views/Form/bootstrap_v1.html.twig:
--------------------------------------------------------------------------------
1 | {% block field_row %}
2 | {% spaceless %}
3 |
4 | {{ form_label(form, label|default(null)) }}
5 |
6 | {{ form_widget(form) }}
7 |
8 |
9 | {{ form_errors(form)}}
10 | {% endspaceless %}
11 | {% endblock field_row %}
12 |
13 | {% block field_errors %}
14 | {% spaceless %}
15 | {% if errors|length > 0 %}
16 |
17 | {% for error in errors %}
18 |
22 | {% endfor %}
23 |
24 | {% endif %}
25 | {% endspaceless %}
26 | {% endblock field_errors %}
27 |
28 | {% block generic_label %}
29 | {% set attr = attr|merge({'class': ''}) %}
30 | {% spaceless %}
31 | {% if required %}
32 | {% set attr = attr|merge({'class': 'required'}) %}
33 | {% endif %}
34 |
35 | {% endspaceless %}
36 | {% endblock %}
--------------------------------------------------------------------------------
/Resources/views/Form/bootstrap_v2.html.twig:
--------------------------------------------------------------------------------
1 | {% block field_row %}
2 | {% spaceless %}
3 |
4 | {{ form_label(form, label|default(null)) }}
5 |
6 | {{ form_widget(form) }}
7 | {{ form_errors(form)}}
8 |
9 |
10 | {% endspaceless %}
11 | {% endblock field_row %}
12 |
13 | {% block field_errors %}
14 | {% spaceless %}
15 | {% if errors|length > 0 %}
16 |
17 | {% for error in errors %}
18 |
19 | {{ error.messageTemplate|trans(error.messageParameters, 'validators') }}
20 |
21 | {% endfor %}
22 |
23 | {% endif %}
24 | {% endspaceless %}
25 | {% endblock field_errors %}
26 |
27 | {% block generic_label %}
28 | {% set attr = attr|merge({'class': ''}) %}
29 | {% spaceless %}
30 | {% if required %}
31 | {% set attr = attr|merge({'class': 'required'}) %}
32 | {% endif %}
33 |
34 | {% endspaceless %}
35 | {% endblock %}
--------------------------------------------------------------------------------
/RuianTwitterBootstrapBundle.php:
--------------------------------------------------------------------------------
1 | =5.3.2",
11 | "symfony/framework-bundle": "2.*",
12 | "twitter/bootstrap": "origin/master",
13 | "twitter/bootstrap": "2.0-wip",
14 | "leafo/lessphp" : "origin/master"
15 | },
16 | "target-dir": "bundles/Ruian/TwitterBootstrapBundle"
17 | }
--------------------------------------------------------------------------------