Skip to content

Commit 748756c

Browse files
committed
Initial commit
0 parents  commit 748756c

8 files changed

+468
-0
lines changed

.editorconfig

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
insert_final_newline = true
7+
indent_style = space
8+
indent_size = 2
9+
trim_trailing_whitespace = true
10+
11+
[*.md]
12+
trim_trailing_whitespace = false
13+
14+
[*.php]
15+
indent_size = 4

LICENSE.md

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2019 Brandon Nifong
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Sage SVG
2+
3+
[![Latest Stable Version](https://poser.pugx.org/log1x/sage-svg/v/stable)](https://packagist.org/packages/log1x/sage-svg)
4+
[![Total Downloads](https://poser.pugx.org/log1x/sage-svg/downloads)](https://packagist.org/packages/log1x/sage-svg)
5+
6+
Sage SVG is a simple package for handling inline SVG's in your Sage 10 projects.
7+
8+
## Requirements
9+
10+
- [Sage](https://github.com/roots/sage) >= 10.0
11+
- [PHP](https://secure.php.net/manual/en/install.php) >= 7.1.3
12+
- [Composer](https://getcomposer.org/download/)
13+
14+
## Installation
15+
16+
Install via Composer:
17+
18+
```bash
19+
$ composer require log1x/sage-svg
20+
```
21+
22+
## Usage
23+
24+
By default, the following paths are checked for your SVG (in order):
25+
26+
- If passed an array containing `id`, it is assumed to be a WordPress attachment and is ran through [`get_attached_file()`](https://codex.wordpress.org/Function_Reference/get_attached_file).
27+
- Your default asset manifest (usually `mix-manifest.json`).
28+
- Path relative to `config('svg.path')` which is `public_path()` (`dist/`) by default.
29+
- Absolute web root path.
30+
31+
### Blade directive
32+
33+
Unless you require advance functionality from somewhere such as a Controller, the best way to use Sage SVG is with the Blade directive straight in your templates.
34+
35+
```php
36+
# Relative path (with dot notation)
37+
@svg('images.logo')
38+
39+
# Absolute path from webroot with `w-32 h-auto` CSS classes and an aria-label
40+
@svg('app/uploads/2019/07/logo.svg', 'w-32 h-auto', ['aria-label' => 'Logo'])
41+
```
42+
43+
### Helper
44+
45+
The easiest way to use SVG outside of a Blade template is the global `get_svg()` helper function. `get_svg()` will return `false` if no image is found.
46+
47+
```php
48+
# Relative path
49+
$image = get_svg('images.logo');
50+
51+
# Absolute path from webroot with `w-32 h-auto` CSS classes
52+
$image = get_svg('app/uploads/2019/07/logo.svg', 'w-32 h-auto');
53+
54+
# WordPress attachment (e.g. ACF field) with `my-logo` CSS class
55+
$image = get_svg(
56+
get_field('logo_svg'),
57+
'my-logo'
58+
);
59+
```
60+
61+
### App Container
62+
63+
While it's easier to use the Helper function, if it not available or sane for your scenario, you can render your SVG using the initialized `SageSvg` instance from the app container.
64+
65+
```php
66+
use function Roots\app;
67+
68+
$image = app(SageSvg::class)->render('images.logo');
69+
```
70+
71+
## Configuration
72+
73+
The configuration file, `svg.php`, can be published using Acorn:
74+
75+
```bash
76+
$ wp acorn vendor:publish --provider='Log1x\SageSvg\SageSvgServiceProvider'
77+
```
78+
79+
You can read the DocBlocks in `config/svg.php` for more details.
80+
81+
## Why another SVG Package?
82+
83+
> Didn't you author Blade SVG Sage? Why another SVG package?
84+
85+
While I do have my fork of [Blade SVG](https://github.com/adamwathan/blade-sage-svg) called [Blade SVG Sage](https://github.com/log1x/blade-svg-sage), I find it rather underwhelming due to the following reasons:
86+
87+
- Unable to handle WordPress attachments
88+
- Unable to inline SVG's that aren't set in a specific path
89+
- Unable to properly use the asset manifest.
90+
- I know QWp6t
91+
92+
## Bug Reports
93+
94+
If you discover a bug in Sage SVG, please [open an issue](https://github.com/log1x/sage-svg/issues).
95+
96+
## Contributing
97+
98+
Contributing whether it be through PRs, reporting an issue, or suggesting an idea is encouraged and appreciated.
99+
100+
## License
101+
102+
Sage SVG is provided under the [MIT License](https://github.com/log1x/sage-svg/blob/master/LICENSE.md).

composer.json

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"name": "log1x/sage-svg",
3+
"type": "package",
4+
"license": "MIT",
5+
"description": "A simple package for handling inline SVG's in Sage 10 projects.",
6+
"authors": [
7+
{
8+
"name": "Brandon Nifong",
9+
"email": "[email protected]"
10+
}
11+
],
12+
"keywords": [
13+
"wordpress",
14+
"sage",
15+
"svg"
16+
],
17+
"support": {
18+
"issues": "https://github.com/log1x/sage-svg/issues"
19+
},
20+
"autoload": {
21+
"psr-4": {
22+
"Log1x\\SageSvg\\": "src/"
23+
},
24+
"files": [
25+
"src/helpers.php"
26+
]
27+
},
28+
"require": {
29+
"php": ">=7.1.3"
30+
},
31+
"extra": {
32+
"acorn": {
33+
"providers": [
34+
"Log1x\\SageSvg\\SageSvgServiceProvider"
35+
]
36+
}
37+
}
38+
}

config/svg.php

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
use function Roots\public_path;
4+
5+
return [
6+
7+
/*
8+
|--------------------------------------------------------------------------
9+
| Path
10+
|--------------------------------------------------------------------------
11+
|
12+
| This value is the default path used by SageSVG for finding SVG files.
13+
| This path is then resolved internally if an absolute path is not being
14+
| used.
15+
|
16+
*/
17+
18+
'path' => public_path(),
19+
20+
/*
21+
|--------------------------------------------------------------------------
22+
| Class
23+
|--------------------------------------------------------------------------
24+
|
25+
| Here you can specify a default class to be added on all inlined SVGs.
26+
| Much like how you would define multiple classes in an HTML attribute,
27+
| you may separate each class using a space.
28+
|
29+
*/
30+
31+
'class' => '',
32+
];

src/SageSvg.php

+175
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
<?php
2+
3+
namespace Log1x\SageSvg;
4+
5+
use Illuminate\Support\HtmlString;
6+
use Illuminate\Support\Str;
7+
use Illuminate\Filesystem\Filesystem;
8+
9+
use function Roots\asset;
10+
11+
class SageSvg
12+
{
13+
/**
14+
* Files
15+
*
16+
* @var \Illuminate\Filesystem\Filesystem
17+
*/
18+
protected $files;
19+
20+
/**
21+
* Config
22+
*
23+
* @var array
24+
*/
25+
protected $config = [
26+
'path' => '',
27+
'class' => ''
28+
];
29+
30+
/**
31+
* Initialize SVG
32+
*
33+
* @param array $config
34+
* @return void
35+
*/
36+
public function __construct($config = [])
37+
{
38+
$this->config = collect($this->config)->merge($config);
39+
$this->cache = collect();
40+
$this->files = new Filesystem;
41+
}
42+
43+
/**
44+
* Render the SVG as HTML
45+
*
46+
* @param string $image
47+
* @param string|array $class
48+
* @param array $attrs
49+
* @return \Illuminate\Support\HtmlString
50+
*/
51+
public function render($image, $class = '', $attrs = [])
52+
{
53+
if (is_array($class)) {
54+
$class = implode(' ', $class);
55+
}
56+
57+
$attrs = collect($attrs)->merge([
58+
'class' => $this->buildClass($class)
59+
])->filter()->all();
60+
61+
return new HtmlString(
62+
str_replace(
63+
'<svg',
64+
sprintf('<svg%s', $this->buildAttributes($attrs)),
65+
$this->get(
66+
$this->prepare($image)
67+
)
68+
)
69+
);
70+
}
71+
72+
/**
73+
* Get SVG from Filesystem
74+
*
75+
* @param string|array $image
76+
* @return mixed
77+
*/
78+
protected function get($image)
79+
{
80+
if (asset($image)->exists()) {
81+
return trim(
82+
asset($image)->contents()
83+
);
84+
}
85+
86+
if ($this->files->exists($image)) {
87+
return trim(
88+
$this->files->get($image)
89+
);
90+
}
91+
92+
if ($this->files->exists($this->withPath($image))) {
93+
return trim(
94+
$this->files->get($this->withPath($image))
95+
);
96+
}
97+
98+
return sprintf('<!-- %s not found. -->', $image);
99+
}
100+
101+
/**
102+
* Return a prepared SVG image path.
103+
*
104+
* @param string|array $image
105+
* @return string
106+
*/
107+
protected function prepare($image)
108+
{
109+
if (is_array($image) && ! empty($image['id'])) {
110+
return get_attached_file($image['id']);
111+
}
112+
113+
if (is_string($image)) {
114+
if (Str::startsWith($image, '/')) {
115+
$image = Str::replaceFirst('/', '', $image);
116+
}
117+
118+
if (! Str::contains($image, '/')) {
119+
$image = str_replace('.', '/', $image);
120+
}
121+
122+
return Str::finish(
123+
strtok($image, '?'),
124+
'.svg'
125+
);
126+
}
127+
128+
return $image;
129+
}
130+
131+
/**
132+
* Return the passed string alongside the config path.
133+
*
134+
* @param string $image
135+
* @return string
136+
*/
137+
protected function withPath($image)
138+
{
139+
return Str::finish($this->config->get('path'), '/') . $image;
140+
}
141+
142+
/**
143+
* Build CSS Classes
144+
*
145+
* @param string $class
146+
* @return string
147+
*/
148+
protected function buildClass($class)
149+
{
150+
return trim(
151+
sprintf('%s %s', $this->config->get('class'), $class)
152+
);
153+
}
154+
155+
/**
156+
* Build element attributes.
157+
*
158+
* @param array $attrs
159+
* @return string
160+
*/
161+
protected function buildAttributes($attrs = [])
162+
{
163+
if (empty($attrs)) {
164+
return '';
165+
}
166+
167+
return ' ' . collect($attrs)->map(function ($value, $attr) {
168+
if (is_int($attr)) {
169+
return $value;
170+
}
171+
172+
return sprintf('%s="%s"', $attr, $value);
173+
})->implode(' ');
174+
}
175+
}

0 commit comments

Comments
 (0)