I was wondering if anyone already worked on a plugin to apply french typography on all contents ?
I mean, replace “TEXT” with « TEXT », adding a unbreakable space before double marks (;, !, ?..) and so on…
I was thinking working on a twig filter but is there a way to apply it onto the contents displayed inside the admin panel, without modifying admin templates ?
I’m using the onPageContentProcessed event to deal with the page.content ; and I’m using the onTwigInitialized event to add the |bettertypo Twig filter I can use on custom header.field. I didn’t find a way to apply the Twig filter on the page.content without having side effects…
The library deals with multiple languages and is quite configurable. I intend to add some options in the Grav plugin.
Great job
Just don’t hold your breath waiting for my tests - I have my hands full for now
Just have some comments looking at the code:
Is plugin really compatible with Grav 1.6.0? It might be, but just to make sure
What are these three warning icons in blueprints? Some unicode symbols?
If you plan at some point publishing this plugin to GPM, I’d really love to see code cleaned up Currently it’s very inconsistent and a bit difficult to read. Also adding PHPDocs at least would be appreciated That’s if you plan to publish it
The plugin hasn’t been tested with the 1.6 version of Grav… I was put by the bin/plugin devtools new-plugin command and I haven’t modified this… But, I’m going to modify this dependency.
in the blueprints.yaml, I’ve just copied what was produced by the PHP-Typography library… I should use a html value instead ?
That would be the point to publish this plugin at some point, if it can be useful to others. I’m not a developer so that can explain why the code is inconsistent… I’ve just noticed I had an indentation issue… Can you point me to what I must deal with ?
There is no way to disable FR specific typography when the page is in french… It’s because I assume you should enable these improvements when dealing with french language, as theye are basics. But if needed, I can add a configuration toggle to enable/disable french language improvements.
Copying is fine, but I think you copied too much. Even editor shows these weird symbols
IMO users should have a choice to enable or disable it. You can leave it on by default
Where to start…
It’s not just indentation, but small things Eg. redundant comments:
// DASH STYLE
if ($config['smart_dashes'] === true) {
IMHO there’s absolutely no need for all of these, when right on the next line you can clearly see what’s happening.
Then the same if statements - what happens if for whatever reason user deletes some config options (eg. smart_dashes)? PHP will yield some errors I would change them to
if (!empty($config['smart_dashes'])) {
}
Then code style - I’d suggest to go through PSR-12 and you’ll get at least an idea Of course it’s your plugin and you decide how it should look, but I think, if you’d like someone else to contribute, it’s much better to have a nice for everyone code to work with. I’m sure I’m guilty myself of not always writing a beautiful code, but I try
About the blueprints.yaml : I’m using VSCode on a Debian based Linux distribution and I don’t see this kind of symbol… I’ll use the HTML entities instead
I’ll propose an option to enable/disable french advanced typographic improvements then.
I’ll try to cleanup my code and I’ll run phpcs & phpcbf with the --standard=PSR12 option to improve it.
Not everyone uses Admin during development or on production server. Provide all variables defined in blueprints.yaml also in better-typography.yaml. Including the documentation and possible options. See eg. /system/config/system.yaml
Use defaults that will fit for most users.
I wonder, should the plugin run on each and every page, or maybe only for certain languages if multiple languages have been set in system.yaml.
Blueprint: blueprints.yaml
Also vscode gives warnings about the special characters: “The character U+200b is invisible. Adjust settings”
I would prefer meaningful variable names that are more “self-documenting”. E.g. useSmartDashes instead of smart_dashes
Use use to import classes:
use PHP_Typography\PHP_Typography;
use PHP_Typography\Settings;
use Twig_SimpleFilter;
[...]
new Twig_SimpleFilter(...);
$settings = new Settings(true);
$typography = new PHP_Typography();
Some If-statements could be removed/refactored:
From:
Using $language = $this->grav['language']->getLanguage();
Using the active language might cause an unexpected behaviour. In a multilingual website, when a page has not been translated for the requested langauge, another language might be used as fallback. Eg. When user requests the Spanish page, a French page might be returned. If user is the first to access the page, the French page is updated and cached. If later the French page is requested, the cache with the Spanish update will be served.
I think the language of the page file itself using Page::langueage() should be used.
With testing only certain languages I mean:
Grav can be setup for multiple languages. I can imagine that not every language needs to replace dashes, quotes and the likes. If so, wouldn’t it then be handly to have a config variable that can be set to an array of languages for which the markdown should be updated. Excluding the available languages which should not be handled by the plugin.
About the language… I’m not sur that using $this->grav['page']->language() is the solution : in my case, on a monolingual site, this return “NULL”… So I should run $this->grav['language']->getLanguage(); after ?
The ideal solution would be to have a language based configuration of the plugin ; each language has its own typographic rules, so we can imagine to declare for each option an array of settings :
Languages : [fr,en,ro]
SmartQuotes: [true,false,true]
QuotesStyles: [doubleGuillemetsFrench,doubleCurled,doubleGuillemets]
What do you think ? Is there a better way ?
But I don’t see how to provide an easy configuration form with this approach…
Thanks again and in advance for any suggestion, improvement…
I think in this case I would go with list field where in each item you can select a language (from available ones) and then all the typography options for it. but also leave separate list of all same options not assigned to any language as a default
So I should run $this->grav['language']->getLanguage(); after ?
I’ve never come across this typography issue, so I wouldn’t know exactly… I would think the plugin should respond to the target audience of the page. So the language set for the page is leading. If no language is set for the page, a default setting should be used.
What if the user’s language is leading? For example, when supported languages are being set as [fr, en, it] but there is only a single 02.typography/default.fr.md available, then browsing to https://domain/fr/typography, https://domain/en/typography and https://domain/it/typography will all be present with the same French page. If the first user is Italian, the page will be processed with Italian settings, cached and reused for all other languages. I don’t think this is the behaviour you’re looking for.
What do you think ? Is there a better way ?
You could try playing with the following:
In php add:
public static function languageList(): array
{
/** @var Grav */
$grav = Grav::instance();
/** @var Data */
$config = $grav['config'];
$languages = [
'default' => 'Default'
];
forEach($config->get('system.languages.supported', []) as $language) {
$languages[$language] = strtoupper($language);
}
return $languages;
}
public static function maxLanguages(): int
{
/** @var Grav */
$grav = Grav::instance();
/** @var Data */
$config = $grav['config'];
return count($config->get('system.languages.supported', [])) + 1;
}
And in your blueprint:
typography:
type: list
style: vertical
label: Language settings
min: 1
data-max@: 'Grav\Plugin\YourPlugin::maxLanguages'
fields:
.language:
type: select
label: Language
data-options@: 'Grav\Plugin\YourPlugin::languageList'
.style:
type: select
label: Style
options:
a: aaa
b: bbb
If no languages have been set, you can only set values for ‘Default’. If languages have been set, you can set Default values, and settings for each available language. For languages without settings, Default can be used.
If I want to release the plugin, how do I need to deal with the PHP Typography library ? Do I need to add the vendor/ folder to the repository or the admin plugin panel runs automatically composer update while installing a plugin ?
just chiming in to say that there are currently two typography plugins that don’t exactly do what you would like, but maybe you’d like to take a peek at the code:
MT uses automatic replacements like what you are doing, TH is a manual thing for Admin editor fields, configurable for any characters you’d like to be able to add.
Hope this helps you in some way. It’s nice to see other people who think typography is important
Anna~
@bricebou, Please note that line 122 shows a deprecation warning on the following function: $settings->set_true_no_break_narrow_space(true);
Tp prevent future issues with your plugin, you might want to remove/replace this function before the maintainer removes the function in a future release.