How to use CSSModules in PHP (non SPA) - php

So I want to use the benefits of CSSModules in a regular PHP project (a wordpress theme to be more specific). I am using webpack with autoprefixer, browsersync, postcss and more to compile and hot reload parts of the project while developing. I understand that there is also a plugin to postcss called postcss-modules which I would like to use.
The plugin is adding hashes to all my css classes and outputting a json with the mappings, as expected. Now I would like to bind one css module (which is a scss-file uncompiled) to each php file (as you would do when using css modules in React). How should I do this? I would still like the css to resist in one large file after compiling.
This is a part of my webpack config:
{
test: /\.(scss|css)$/,
use: extractSass.extract({
use: [{
loader: "css-loader"
},
{
loader: 'postcss-loader',
options: {
plugins: function () {
return [
require('precss'),
require('autoprefixer'),
require('cssnano'),
require('postcss-modules')
];
}
}
},
{
loader: "sass-loader"
}],
fallback: "style-loader"
})
},
And I am using a main.js and a style.scss as entry point in webpack. The style.scss is then importing all the partial scss-files (which should be one css module each).

I did a really good writeup on how to do all this. The only difference is I am using grunt-postcss instead of Webpack to handle the postcss plugins and functionality. Should be straightforward to port the concepts over to Webpack.
The key is to configure postcss-modules to handle the separate pcss files as modules. That way you can parse the JSON separately per module. Using globalModulePaths you are able to keep your main pcss intact and append your modules to it.

Related

Integrating Gulp and bower into Zend Project

The issue is, I would like to use all benefits of tasks runner and bower into my existing Zend-Project. I'm not sure, how should I restructure my whole project folder.
My current structure looks like follows:
config
module
vendor
public
css
js
libs
jquery
bootstrap
controller1
jsController1.
etc
index.php
From this (Gulp and Bower - creating proper files structure) I know, that I have to create a separate folder to save all libraries installed from bower and then I have to copy them with gulp into the public folder. Now depending on enviroment (Production or Development) I want to use minified css and js scripts. So should I create 2 public - folders and depending on enviroment change base path for zend? Or what's the best way to perform that?
Additionally I would like to integrate browser-sync into this project (cause of livereload). Therefore I want to use gulp-connect to start the php-server. But then the enviroment variables from apache are not set. How can I set it? According to documentation I have to add newArgs (cause my Options are array) "APPLICATION_ENV=development". But if add this after comma, i get error: "Could not open input file: APPLICATION_ENV=development"
My currenty gulfile:
var gulp = require('gulp'),
php = require('gulp-connect-php');
gulp.task('php', function() {
php.server({
configCallback: function _configCallback(type, collection) {
// If you wish to leave one of the argument types alone, simply return the passed in collection.
if (type === php.OPTIONS_SPAWN_OBJ) { // As the constant suggests, collection is an Object.
// Lets add a custom env var. Good for injecting AWS_RDS config variables.
collection.env = Object.assign({
APPLICATION_ENV: "development"
}, process.env);
return collection;
} else if (type === php.OPTIONS_PHP_CLI_ARR) { // As the constant suggests, collection is an Array.
let newArgs = [
'-e', // Generate extended information for debugger/profiler.
'-d', 'memory_limit=2G' // Define INI entry, Up memory limit to 2G.
,"APPLICATION_ENV=development"
];
// Ensure our argument switches appear before the rest.
return newArgs.concat(collection);
}
}
,
base: 'public',
port: 8010,
keepalive: true},
function _connected_callback() {
console.log("PHP Development Server Connected.");
});
}
);

Can I use the Blade templating engine outside of Laravel?

i'm want to creating a design pattern and use the "Blade templating engine".
Can I use the Blade templating engine outside of Laravel and use it in my new pattern ?
For the record:
I tested many libraries to run blade outside Laravel (that i don't use) and most are poor hacks of the original library that simply copied and pasted the code and removed some dependencies yet it retains a lot of dependencies of Laravel.
So I created (for a project) an alternative for blade that its free (MIT license, i.e. close source/private code is OK) in a single file and without a single dependency of an external library. You could download the class and start using it, or you could install via composer.
https://github.com/EFTEC/BladeOne
https://packagist.org/packages/eftec/bladeone
It's 100% compatible without the Laravel's own features (extensions).
How it works:
<?php
include "lib/BladeOne/BladeOne.php";
use eftec\bladeone;
$views = __DIR__ . '/views'; // folder where is located the templates
$compiledFolder = __DIR__ . '/compiled';
$blade=new bladeone\BladeOne($views,$compiledFolder);
echo $blade->run("Test.hello", ["name" => "hola mundo"]);
?>
Another alternative is to use twig but I tested it and I don't like it. I like the syntax of Laravel that its close to ASP.NET MVC Razor.
Edit: To this date (July 2018), it's practically the only template system that supports the new features of Blade 5.6 without Laravel. ;-)
You certainly can, there are lots of standalone blade options on packagist, as long as you are comfortable with composer then there should be no issue, this one looks pretty interesting due to having a really high percentage of stars compared to downloads.
Be warned though i have not tried it myself, like you i was looking for a standalone option for my own project and came across it, i will be giving it a real good workout though at sometime in the near future,
Matt Stauffer has created a whole repository showing you how you can use various Illuminate components directly outside of Laravel. I would recommend following his example and looking at his source code.
https://github.com/mattstauffer/Torch
Here is the index.php of using Laravel Views outside of Laravel
https://github.com/mattstauffer/Torch/blob/master/components/view/index.php
You can write a custom wrapper around it so that you can call it like Laravel
use Illuminate\Container\Container;
use Illuminate\Events\Dispatcher;
use Illuminate\Filesystem\Filesystem;
use Illuminate\View\Compilers\BladeCompiler;
use Illuminate\View\Engines\CompilerEngine;
use Illuminate\View\Engines\EngineResolver;
use Illuminate\View\Engines\PhpEngine;
use Illuminate\View\Factory;
use Illuminate\View\FileViewFinder;
function view($viewName, $templateData)
{
// Configuration
// Note that you can set several directories where your templates are located
$pathsToTemplates = [__DIR__ . '/templates'];
$pathToCompiledTemplates = __DIR__ . '/compiled';
// Dependencies
$filesystem = new Filesystem;
$eventDispatcher = new Dispatcher(new Container);
// Create View Factory capable of rendering PHP and Blade templates
$viewResolver = new EngineResolver;
$bladeCompiler = new BladeCompiler($filesystem, $pathToCompiledTemplates);
$viewResolver->register('blade', function () use ($bladeCompiler) {
return new CompilerEngine($bladeCompiler);
});
$viewResolver->register('php', function () {
return new PhpEngine;
});
$viewFinder = new FileViewFinder($filesystem, $pathsToTemplates);
$viewFactory = new Factory($viewResolver, $viewFinder, $eventDispatcher);
// Render template
return $viewFactory->make($viewName, $templateData)->render();
}
You can then call this using the following
view('view.name', ['title' => 'Title', 'text' => 'This is text']);
Yes you can use it where ever you like. Just install one of the the many packages available on composer for it.
If you're interested in integrating it with codeigniter I have a blog post here outlining the process.
Following the above steps should make it obvious how to include it into any framework.

Elixir versioning with SCSS and JavaScript

How do I chain Elixir's .version() method with others? My gulpfile.js looks like this:
elixir(function(mix) {
mix.sass("frontend/frontend.scss", "public/css/app.css")
.sass("backend/backend.scss", "public/css/admin.css")
.scripts(js, "public/js/app.js");
});
Do I just call .version() after this chain on my generated files? Like this:
elixir(function(mix) {
mix.sass("frontend/frontend.scss", "public/css/app.css")
.sass("backend/backend.scss", "public/css/admin.css")
.scripts(js, "public/js/app.js")
.version(["public/css/app.css", "public/css/admin.css", "public/js/app.js"]);
});
Or is there some way to combine .sass() and .scripts() methods with .version() to avoid repeating file names?
Another problem with my example is that it produces redundant unversioned files prior to creating versioned ones, so I have useless files there.
You said it. The only way to version based on what the laravel docs says is too chain .version([path_to_public_file]). If you would like to make sure for yourself, the docs are here: https://laravel.com/docs/5.0/elixir.

Symfony 2 - how to parse %parameter% in my own Yaml file loader?

I have a Yaml loader that loads additional config items for a "profile" (where one application can use different profiles, e.g. for different local editions of the same site).
My loader is very simple:
# YamlProfileLoader.php
use Symfony\Component\Config\Loader\FileLoader;
use Symfony\Component\Yaml\Yaml;
class YamlProfileLoader extends FileLoader
{
public function load($resource, $type = null)
{
$configValues = Yaml::parse($resource);
return $configValues;
}
public function supports($resource, $type = null)
{
return is_string($resource) && 'yml' === pathinfo(
$resource,
PATHINFO_EXTENSION
);
}
}
The loader is used more or less like this (simplified a bit, because there is caching too):
$loaderResolver = new LoaderResolver(array(new YamlProfileLoader($locator)));
$delegatingLoader = new DelegatingLoader($loaderResolver);
foreach ($yamlProfileFiles as $yamlProfileFile) {
$profileName = basename($yamlProfileFile, '.yml');
$profiles[$profileName] = $delegatingLoader->load($yamlProfileFile);
}
So is the Yaml file it's parsing:
# profiles/germany.yml
locale: de_DE
hostname: %profiles.germany.host_name%
At the moment, the resulting array contains literally '%profiles.germany.host_name%' for the 'hostname' array key.
So, how can I parse the % parameters to get the actual parameter values?
I've been trawling through the Symfony 2 code and docs (and this SO question and can't find where this is done within the framework itself. I could probably write my own parameter parser - get the parameters from the kernel, search for the %foo% strings and look-up/replace... but if there's a component ready to be used, I prefer to use this.
To give a bit more background, why I can't just include it into the main config.yml: I want to be able to load app/config/profiles/*.yml, where * is the profile name, and I am using my own Loader to accomplish this. If there's a way to wildcard import config files, then that might also work for me.
Note: currently using 2.4 but just about ready to upgrade to 2.5 if that helps.
I've been trawling through the Symfony 2 code and docs (and this SO question and can't find where this is done within the framework itself.
Symfony's dependency injection component uses a compiler pass to resolve parameter references during the optimisation phase.
The Compiler gets the registered compiler passes from its PassConfig instance. This class configures a few compiler passes by default, which includes the ResolveParameterPlaceHoldersPass.
During container compilation, the ResolveParameterPlaceHoldersPass uses the Container's ParameterBag to resolve strings containing %parameters%. The compiler pass then sets that resolved value back into the container.
So, how can I parse the % parameters to get the actual parameter values?
You'd need access to the container in your ProfileLoader (or wherever you see fit). Using the container, you can recursively iterate over your parsed yaml config and pass values to the container's parameter bag to be resolved via the resolveValue() method.
Seems to me like perhaps a cleaner approach would be for you to implement this in your bundle configuration. That way your config will be validated against a defined structure, which can catch configuration errors early. See the docs on bundle configuration for more information (that link is for v2.7, but hopefully will apply to your version also).
I realise this is an old question, but I have spent quite a while figuring this out for my own projects, so I'm posting the answer here for future reference.
I tried a lot of options to resolve %parameter% to parameters.yml but no luck at all. All I can think of is parsing %parameter% and fetch it from container, no innovation yet.
On the other hand I don't have enough information about your environment to see the big picture but I just come up with another idea. It can be quite handy if you declare your profiles in your parameters.yml file and load it as an array in your controller or service via container.
app/config/parameters.yml
parameters:
profiles:
germany:
locale: de_DE
host_name: http://de.example.com
uk:
locale: en_EN
host_name: http://uk.example.com
turkey:
locale: tr_TR
host_name: http://tr.example.com
You can have all your profiles as an array in your controller.
<?php
namespace Acme\DemoBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
public function indexAction()
{
$profiles = $this->container->getParameter('profiles');
var_dump($profiles);
return $this->render('AcmeDemoBundle:Default:index.html.twig');
}
}
With this approach
you don't have to code a custom YamlLoader
you don't have to worry about importing parameters into other yml files
you can have your profiles as an array anytime you have the $container in your hand
you don't have to load/cache profile files one by one
you don't have to find a wildcard file loading solution
If I got your question correctly, this approach can help you.

Controlling Exact Folder/Directory where Packages are Written by Composer for PHP

The Background
I'm trying to use Composer to manage dependencies for WordPress plugins. I've built several PHP libraries (RESTian & Sidecar) I want to include in subdirectories for each of several plugins we are building and those PHP libraries are hosted on GitHub. The WordPress plugins are (currently) hosted in private BitBucket repos as they are for clients but those plugins will also get published to WordPress plugin repository when we are ready to release them.
The Problem
I want a directory structure of /libraries/restian/ and /libraries/sidecar/ relative to the root of the plugin. For those who know WordPress they would ultimately look like this installed:
/wp-content/plugins/my-wp-plugin/libraries/restian/
/wp-content/plugins/my-wp-plugin/libraries/sidecar/
Problem is I've only been able to get Composer to put them within a /newclarity/ subdirectory which is more complexity than I want to add to the directory structure of the plugin ('newclarity' is our GitHub account):
/wp-content/plugins/my-wp-plugin/libraries/newclarity/restian/
/wp-content/plugins/my-wp-plugin/libraries/newclarity/sidecar/
The Source
Here is the composer.json file that I am using to research and test this:
{
"name":"mikeschinkel/my-wp-plugin",
"description":"My WordPress Plugin",
"type":"wordpress-plugin",
"config":{
"vendor-dir":"libraries/"
},
"require": {
"newclarity/restian":"dev-master",
"newclarity/sidecar":"dev-master"
},
"repositories":[
{
"type":"git",
"url":"https://github.com/newclarity/restian.git"
},
{
"type":"git",
"url":"https://github.com/newclarity/sidecar.git"
}
]
}
And here are the current composer.json files from the libraries hosted at GitHub:
{
"name": "newclarity/restian",
"description": "RESTian: A base class library to simplify building RESTful/Web API clients in PHP",
"require": {
"php": ">=5.2.4"
}
}
And:
{
"name": "newclarity/sidecar",
"description": "Sidecar: The Missing Plugin API for WordPress",
"require":{
"php":">=5.2.4"
}
}
I've been researching this for over 4 hours now. Any help would be appreciated.
-Mike
You can try to use the wordpress-plugin type combined with the composer/installers package. Read more about this on the Installers README. It should do what you want.
Problem is I've only been able to get Composer to put them within a /newclarity/ subdirectory which is more complexity than I want to add to the directory structure of the plugin ('newclarity' is our GitHub account):
Nope, thats not true, at least not true in how you meant it. Composer creates the newclarity-folder, because you specify it within the composer.json as part of the package name, for example
"name": "newclarity/sidecar"
I don't know exactly, but you can try to just name it "sidecar". However, this is discouraged as conflicts between packages become more and more probably the more packages exists, thus you should stay with the two-level folder structure, if there is no higher requirement, that prevent this.
So I came up with a solution that works, but it's inelegant and I was really hoping for a simple and elegant solution hence why I posted my question here on StackOverflow.
After no better answer here I posted on the Composer forum as a feature request and had the request closed because "where code is installed in most cases should not matter." It's sad that some people feel that what they value are the only things worth valuing.
Since it seems like there's no official way to do this and no interest on behalf of the Composer team to make it easier I decided to go ahead and post my solution in case others are beating their head against the wall in same way. It's ugly but it works.
Instead of referencing a Git repo create an "inline package" for each repo; here's what it looks like (NOTE: I added '#' comments which are of course not valid JSON but only here to callout what I changed.):
{
"name":"mikeschinkel/my-wp-plugin",
"description":"My WordPress Plugin",
"type":"wordpress-plugin",
"config":{
"vendor-dir":"libraries"
},
"require": {
"restian":"dev-master", # Short name 'restian' used here.
"sidecar":"dev-master" # Short name 'sidecar' used here.
},
"repositories":[
{
"type":"package", # type=package vs. type=git
"package":{
"name":"sidecar", # Short name 'sidecar' used here.
"version":"dev-master",
"source":{ # This could be "dist" or "source"
"type":"git",
"url":"https://github.com/newclarity/sidecar",
"reference":"master"
}
}
},
{
"type":"package", # type=package vs. type=git
"package":{
"name":"restian", # Short name 'restian' used here.
"version":"dev-master",
"source":{ # This could be "dist" or "source"
"type":"git",
"url":"https://github.com/newclarity/restian",
"reference":"master"
}
}
}
]
}
Given that I'm new to Composer there might be numerous ways I could improve this; any suggestions are welcome. Either way I hope this helps others trying to achieve the same goal.

Categories