-
Posts
130 -
Joined
Everything posted by nurkka
-
Hi @bernhard, I really like to work with RockFrontend (and RockPageBuilder)! Now I have some questions resp. want to make sure what would be the best practice: I am using the autoload-layout feature and am loading a _layout.latte file. But I also would want to make some template specific modifications, like having an element on the startpage, which is not included on all the other pages. I can add this element in home.php, but then it will be included before the opening <html>-tag. When I put the elements into home.latte, this file won't be output until I add the {do $rockfrontend->noLayoutFile = true} directive to it. But if I add this line, the home.latte will of course override my _layout.latte, which is also not what I want. So I added the following to my _layout.latte: ... {* only on the startpage *} {if $page->id==1} {include "src/latte/partials/custom-element.latte"} {/if} </body> </html> - Is this currently a recommended way to e.g. have a custom element on the startpage? - I noticed that content in home.php will always be added to the output, while home.latte will only be added, when using {do $rockfrontend->noLayoutFile = true} in it. Is it possible to load home.latte while preserving _layout.latte, too? - Is RockFrontend compatible with ProcessWire's MarkupRegions? => I removed _main.latte and am now rendering the template-specific latte-files "manually". With "echo" in the respective template PHP-files, and using a _output.php, ProcessWire's markup regions work. But I think one cannot use both techniques, _main.latte and Markup Regions, at the same time. Also, _rockfrontend.php has to be deactivated.* - Currently the page in the docs regarding the render()-method is empty. https://www.baumrock.com/en/processwire/modules/rockfrontend/docs/render/ - Is it possible to render any latte-file with render()? Then I could render home.latte within home.php ... but I would again need MarkupRegions to insert the rendered markup in the right place. I tried it, but with no luck so far. => RockFrontend's render() method can render any latte-file. The trick is to omit _main.latte and implement a more "traditional" approach, with a custom _output.php, in which the Markup Regions are put together.* Maybe you have any clues ... and what method would you use to insert template specific markup while using a global _layout.latte template? * Of course, the purpose of RockFrontend is not to only use the render()-method, so I recommend to not use Markup Regions and use the full feature set of RockFrontend instead. Also, it could be that I have overlooked something, so this information may be subject to change. Edit: Answered some of the questions
-
TailwindCSS suggestions/autocomplete in LATTE files with PHPStorm
nurkka replied to nurkka's topic in RockFrontend
At least it's also not working in PHP and HTML files, so my installation/plugin/whatever must be broken. I am getting no error messages out of PHPStorm. I also tried several different nodejs versions via nvm, but that also didn't work. I don't know how to downgrade the tailwindcss plugin, so I'll leave it there – perhaps the feature will be back with an update sometime. Thank you @Sanyaissues -
TailwindCSS suggestions/autocomplete in LATTE files with PHPStorm
nurkka replied to nurkka's topic in RockFrontend
Thanks @Sanyaissues , I tried that before, but it didn't work for me. Maybe my installation of PHPStorm has issues ... -
I also had to switch from LESS to SASS now. That was possible this way: 1.) Install bernhard's SASS module: https://processwire.com/modules/scss/ 2.) Change asset loading to the following: $rockfrontend->styles() // add tailwindcss provided by RockFrontend ->add('/site/templates/bundle/tailwind.css') // add custom styles ->add('/site/templates/src/scss/custom.scss') // minify on production // note: this does not concatenate the files ->minify( $config->debug ? false : true ) ; Note that the SCSS entrypoint file is loaded with add(). With the SCSS parser, one doesn't have to load the whole SCSS-folder with addAll() as described above regarding LESS. And it also works recursively without setting the recursion depth. I tested it until 3 levels deep. 3.) If you want to use UIKit, add this to your SCSS entry point file (example): // 1. Your custom variables and variable overwrites. $global-link-color: #DA7D02; // 2. Import default variables and available mixins. @import '../../uikit/src/scss/variables-theme.scss'; @import '../../uikit/src/scss/mixins-theme.scss'; // 3. Your custom mixin overwrites. @mixin hook-card() { color: #000; } // 4. Import UIkit. @import '../../uikit/src/scss/uikit-theme'; Note that the example is taken from https://getuikit.com/docs/sass . I tested this, and it works. Please adjust the file paths according to where your SCSS entry point file is placed. Also note that the SASS module uses https://github.com/scssphp/scssphp . This library does not support for example @use . I had to change all my "math.div()" back to "/". But the SCSSPHP team announced that they will support newer SCSS features with the upcoming 2.0 release. So it's just a matter of time.
-
Today, I noticed that when you are using LESS with subfolders nested deeper than 2 levels, the LESS parser does not parse changed files in that deeper nested folders. You have to use addAll() instead of add() to tell the LESS parser to also consider these files. And you have to set the recursion depth to the depth you need. I compared the resulting CSS files and found no other differences between using add('/src/less/myproject.less') and addAll('/src/less'), i.e. addAll() does not add the nested LESS files twice, even if they are imported in the main LESS entrypoint file via @import. Example: <?php $rockfrontend->styles() ->addAll('/src/less', '', 4)
-
RockFrontend – How to use TailwindCSS and LESS together?
nurkka replied to nurkka's topic in RockFrontend
Thanks @wbmnfktr ! Yes, it would be possible to use modern CSS in RockFrontend's site/templates/_tailwind.css. I am not using CSS with nesting etc. yet, because I often had isses with clients with some old devices, so I am getting a bit conservative over time regarding bleeding edge technology 🙂 Perhaps I should reconsider that ... But I also like the possibility of merging my dozens of css/scss/less files together into one single file for production, and this keeps me using preprocessors still. I used TailwindCSS together with SCSS some time ago in a project, where it worked like I described it. I.e. I could use TailwindCSS classes within my SCSS files and also @apply e.g. fonts I defined in tailwind.config.js. In the meantime, I looked into that old project again and found that one cannot use @extend (or &:extend() in LESS), but has to use @apply to extend custom classes with TailwindCSS classes. https://tailwindcss.com/docs/using-with-preprocessors The trick is, to integrate LESS with PostCSS. In RockFrontend, TailwindCSS is compiled via a npm script and LESS is compiled via a PHP library. So, the question is, how could that be combined? Perhaps I'll find the time to have a closer look at that. For the time being, I copied my font definitons and some other stuff from tailwind.config.js over to my LESS files and will just use TailwindCSS's utility classes within the LATTE files. -
Today, I got stuck with RockFrontend, LESS and TailwindCSS. I tried several approaches, but couldn't get it to work. I've got the following problem: I want to use TailwindCSS and LESS together, i.e. be able to use TailwindCSS classes within LESS with e.g. .myclass { &:extend(.text-center); }. Also, I would like to use for example @apply font-serif; within LESS. It seems that this doesn't work, because Tailwind and LESS are separated in RockFrontend, and do not know about each other. My hope was to get rid of npm build scripts, although I know that RockFrontend is also using a npm build script behind the scenes. Is there or would there be a way in the future to integrate TailwindCSS and LESS in a way so they know about each other and can be used together? Or am I missing something?
-
Hi @bernhard, thanks for your reply! RockFrontend, RockPageBuilder, AdminStyleRock, RockShell, RockAdminTweaks and RockMigrations. Thanks for the info – then I misunderstood the feature. In most cases, I am still working with one css and one js file per website. I assume that RockPageBuilder only adds the block specific styles and scripts when they are really needed on a specific page, so concatenating and compiling everything into single files wouldn't work. Currently I only have them locally within a DDEV container and I would not copy them into the forum, so for the moment only have the full paths of those 2 files. But I assume they must be the same as in your GitHub repos, so perhaps the info is ok: /site/modules/RockFields/assets/RockPageBuilder.min.css /site/modules/RockFrontend/RockFrontend.min.js I had a closer look: RockFrontend.min.js has code to handle the consent manager and scrollclass features. RockPageBuilder.min.css has styles for handling margins, paddings, alignment etc. I assume these are styles which are needed for the Frontend Editor. I currently believe that I would not need both of the files in my frontend, when it's visited by guest users, as I am not using the mentioned features. Would it be possible via a hook to check if debug mode is off and the current request comes from a guest user, and remove the files from the scripts and styles arrays before they are rendered?
-
@bernhard Hi Bernhard, I found this info from @Stefanowitsch here, but it seems to be outdated. I set up a new website with all new versions of RockSuite today, and my added scripts and styles are not compiled into one JS or one CSS file. RockFrontend keeps them as single script and style files. Is it possible to minify and concatenate scripts and styles to compile them into one single script file and one single styles file? Additionally, I would want to prevent RockPageBuilder.min.css and RockFrontend.min.js from being loaded in the Frontend when debug mode is off and the site is not accessed by a superuser or frontend editor user. Is that possible?
-
RockSettings - Manage common site settings like a boss.
nurkka replied to bernhard's topic in Modules/Plugins
I had similar issed with localPath. After some testing I found out that localPath seems to be not a "real" method of Page, but is registered via a hook. Is it possible that the issue "Page::localPath does not exist or is not callable in this context" is a side effect of that? # /wire/modules/LanguageSupport/LanguageSupportPageNames.module public function ready() { $this->addHook('Page::localPath', $this, 'hookPageLocalPath'); } /** * Add a Page::localPath function with optional $language as argument * * event param Language|string|int Optional language * event return string Localized language path * * @param HookEvent $event * */ public function hookPageLocalPath(HookEvent $event) { /** @var Page $page */ $page = $event->object; $language = $this->getLanguage($event->arguments(0)); $event->return = $this->getPagePath($page, $language); } In my case I could simply replace localPath with path, because localPath returns the page path of the default language and not the page path of the current language. This seems to be an inaccuracy in the docs. See this post: -
Hi all! After I upgraded a site to PHP 8.2, the output of a german month name from a ProcessWire DateTime field didn't work anymore. It always output e.g. "July" instead of "Juli". I tried to set the locale in config.php by adding setlocale(LC_ALL, 'de_DE.UTF-8'); but that didn't change anything. As strftime is deprecated in modern PHP versions, I had to add the following code to output the date correctly in german: <?php $formatter = new \IntlDateFormatter( 'de_DE', \IntlDateFormatter::FULL, \IntlDateFormatter::NONE); $formatter->setPattern('d. MMMM yyyy'); $formatted_date = $formatter->format( $page->getUnformatted('cb_date') ); ?> <p class="cb_news_date"><?= $formatted_date ?></p> Please note that I did not install a german language pack because I wanted to omit the overhead of installing and handling the language modules. I tried to find IntlDateFormatter within /wire/, but obviously ProcessWire generates the month names in another way. I also tried to overwrite "July" with "Juli" in the WireDateTime class (for test purposes), but the month name did not change. How does ProcessWire generate the datetime output and why does it not regard the current locale anymore? Is the ProcessWire way to do solve this, to install language support and translate text strings? But if they are not in WireDateTime.php, as I have tested, where are they located instead?
-
RockFrontend 🔥🚀 The Powerful Toolbox for ProcessWire Frontend Development
nurkka replied to bernhard's topic in RockFrontend
Using RockFrontend in a real project for the first time since yesterday – I'm totally blown away! Currently I am only using Latte templates and LiveReload, but these two features alone are such game changers. @bernhard Thank you so much (again!) for donating such a genius module to the community! I don't know if anybody already asked/answered this, so I'll leave this info here: If you want to add additional folders to be watched by LiveReload, you can define them this way: /site/config.php: $config->livereload = [ 'interval' => 1, 'include' => [ $config->paths->root . '/some/folder', $config->paths->root . '/another/folder', ], ]; -
module Fluency - The complete translation enhancement suite for ProcessWire
nurkka replied to FireWire's topic in Modules/Plugins
In my current project, the default language is German and the second language is English. Now, I am using Ryan's LoginRegisterPro module, which is of course in English. I wanted to use Fluency to translate all fields in the language translator to German, but that's not possible. This is because Fluency does only translate from the first to the second (and other) languages, but not from "string constant in a php file" to the first language. At least in my case, it always copied the string constant into the field, which is in English. So, I changed my setup and made the default language English and the second language German, and now it worked: Fluency translated all strings from the module php file to German in one step. But now, I have the problem, that I can't leave the website with German as the second language, because to my knowledge that's only possible, if one has language tokens in the urls, also for the default language, and makes a redirect to the desired language. But that's no option in this project. Setting the guest user language to the second language (now German) didn't help either. My workaround now is, to export the translated JSON files, then switch the languages back to default = German and second = English, and import the translated JSON file(s) to the German language. So I have some questions: - Has anybody already found a better solution for this problem? - @FireWire Would it be possible to add a feature to Fluency, to be able to translate module or template files (which are mostly in English) also to the default language (for cases where it is a non-English language)?- 221 replies
-
- 1
-
- translation
- language
-
(and 1 more)
Tagged with:
-
In this case, the setup is for a legacy project, and I am still experimenting, which is the best setup for me. In this project, I have lots and lots of RepeaterMatrix items, with nested Repeaters, Fieldset Pages, Combo fields and of course a lot of "simple" fields, like text_1 to text_20 etc. I will not be able to refactor everything into migrations, because that would be too much work. But for new fields, I wanted to use RockMigrations. RockMigrations only adds things and does not remove anything, until you tell it to, so it is perfect for this use case. Thanks for pointing out, that the migrations must be executed in the right order. I hope that this won't be a problem in my case, although I don't know for sure yet. Having all migrations in migrate.php or in Site.module.php would stress me out, because I would have hundreds of lines of code in one file. Currently, I am only adding new fields, and I am grouping the migrations accordingly. E.g. when adding a fieldset page, I wrote a migration file with all its dependent fields and the fieldset page at the end. When adding a RepeaterMatrix item, I would define all the dependent fields and the RepeaterMatrix item migration in one file. So I would always try to group migrations which are connected/dependent into one file. Of course, this is not perfect, because I also use "global" fields like "text_1" in my RepeaterMatrix items. In a new project, I would probably simply add a new text field for every RepeaterMatrix item, if needed. I am sure, one could also write a custom page class for a RepeaterMatrix item, and add the migrations there, but I have to learn this yet. Perhaps it's also better not to mix several ways to integrate migrations, because of the maintainability of the site. Anyway, I am really happy with the new setup for now ?
-
@bernhard Thanks for your reply and valuable info! I wanted to try RockPageBuilder for some time, but I am still working on legacy projects. I will make a completely new website in september, so that will be my opportunity to finally use it. As for the case described above, where I want to have different migration files for different fields, templates, etc, I found a solution. It is possbile to tell RockMigrations to watch a whole folder and also to watch it recursively, by using rockmigrations()->watch( 'DIRECTORYNAME', true, [ 'recursive' => true ] ); So this works now: <?php namespace ProcessWire; class Site extends WireData implements Module { public static function getModuleInfo() { return [ 'title' => 'Site', 'singular' => true, 'autoload' => true, ]; } public function init() { $rm = $this->wire->modules->get('RockMigrations'); if ($rm) { // $rm->watch($this); // not needed b/c we have no migrations directly in this module class file $rm->watch( __DIR__ . '/migrations', true, [ 'recursive' => true ] ); } } // not needed anymore b/c of $rm->watch in init() /* public function migrate() { $this->migrate_fields(); } public function migrate_fields () { include __DIR__ . '/migrations/fields/fieldset_visible_responsive.php'; include __DIR__ . '/migrations/fields/fieldset_visible_language.php'; } */ } This way, I can have a lean Site.module.php and move all migrations to dedicated files.
-
I am still trying to wrap my head around RockMigrations. With my first attempts, my migrate.php grew to several hundred lines, so I wanted to structure the migrations. I also read that @bernhard always uses a module Site.module.php, which I also created in my project. I also wanted to split my migrations into several files, so I did the following: Directory structure: - modules - Site - migrations - fields fieldset_visible_responsive.php fieldset_visible_language.php Site.module.php Site.module.php <?php namespace ProcessWire; class Site extends WireData implements Module { public static function getModuleInfo() { return [ 'title' => 'Site', 'singular' => true, 'autoload' => true, ]; } public function init() { $rm = $this->wire->modules->get('RockMigrations'); if ($rm) { $rm->watch($this); $rm->watch( __DIR__ . '/migrations/fields/fieldset_visible_responsive.php' ); } } public function migrate() { $this->migrate_fields(); } public function migrate_fields () { include __DIR__ . '/migrations/fields/fieldset_visible_responsive.php'; } } fieldset_visible_responsive.php <?php namespace ProcessWire; $rm = rockmigrations(); $rm->createField('checkbox_visible_responsive_mobile', 'FieldtypeCheckbox', [ 'columnWidth' => 33, 'label' => 'Mobile', ]); [...] Now, I have some questions: - Is there a RockMigrations feature to combine the "watch" command with an "include"? As the watch commands apparently have to be placed in init() and the migrations in migrate(), the migration files to be included have to be referenced in both places. Okay, I could write a config array or something for this, but is there a _native_ RockMigrations feature or best practice for that? - I guess you also do not put all your migrations into Site.module.php – What is your strategy for staying on top of things? Assuming one has lots and lots of "global" fields, which are not related to specific templates, for what you would perhaps use custom page classes. - Is the .php suffix mandatory for the Site-module, or can it also be named Site.module, like other ProcessWire modules? @bernhard And thanks again for the module! I think it's fantastic that you have donated such an impressive module to the community. Even as I am not 100% grasping all the possibilities and features of RockMigrations yet, I think the possibility to create and modify fields by configuration could (and should) also become part of the core. I think other CMS/CMF are already doing that.
-
Here are some additional feature ideas: - The feature to define the TinyMCE-configuration of all your TinyMCE fields in a "parent"-field is so great - how about if we could have that with more fieldtypes? In my sites, I have tons of fields, which change from time to time, and as one can't use fields more than once on a template, I have e.g. image_single_1, image_single_2, image_single_3. It would be great to change all those e.g. image fields at once, by just changing a "parent field". Please tell me, if I missed that feature, if it already exists ? - Nearly all my sites have to be MultiLanguage sites, and therefore, a multilanguage image field would be great. I know Language-alternate fields, but a "real" field would be really great. The most complex project, I am working on, has currently 10 languages. When creating and maintaining all the needed fields, this is a lot of work, which could be much easier with a multilanguage image field. - As I am still working with (nested) RepeaterMatrix and Repeater fields, keeping track of fields which are really used or not used is a complicated, as simple fields often are displayed as "in use" on some pages, while those pages are not "real" pages, but system pages of repeaters. I hope you know what I mean. The feature suggestion in this case is to extend the display of fields on the fields admin page so the relations between the fields are somehow more comprehensible. - Also, the fields list get's confusing, if you have some hundred fields – the UI could be refined somehow, to make the fields list easier to work with.* * I'll try to start a thread about naming fields, because I tend to change my naming scheme with every project, because I try to find the perfect one - which I did't find yet. Perhaps you are willing to share your naming schemes. I am sure someone already invented the perfect scheme ?
-
New post – Implementing and using TinyMCE 6 in ProcessWire
nurkka replied to ryan's topic in News & Announcements
I noticed, that when using a TinyMCE-Field as a "template" for the configuration other TinyMCE-Fields, the "parent" field can be deleted without warning. @ryan Would it be possible to include a warning, like with "normal" fields? Additonally, another feature "wish": It would be great, if all TinyMCE-options would be configurable by text/json-files. Currently, some features can only be changed by copy/pasting code into backend fields, like "Extra CSS styles". -
Additional info: I just noticed that these two variants don't work the same: // this works: $this->addHookAfter( 'Pages::saved(status<' . Page::statusTrash . ')', $this, 'hookPageSaved', [ 'priority' => 200 ] ); // this does not work: $this->addHookAfter( 'Pages::saved(status<trash)', $this, 'hookPageSaved', [ 'priority' => 200 ] ); In my case, I have a module which writes the pages as JSON files to disk, after they are saved. As a page will be saved, when moving it to the trash, the hook will be called either. The selector in the first variant prevents this, while the selector in the second variant doesn't.
-
@ryan you're right, my checkbox was configured to be a "reversed checkbox" via the module CheckboxReversed. I changed the value to 0 and now it works perfectly.
-
I am trying to learn more about Advanced Hooks, and the following worked perfectly: // this works perfectly: $this->addHookAfter( 'Pages::saved(status<' . Page::statusTrash . ')', $this, 'hookPageSaved', [ 'priority' => 200 ] ); This adds the hook only if the saved page is not already in the trash, and executes the hook as late as possible. Now, I would like to add the hook only, if a certain checkbox on the page is checked. I tried the following: // this does not work: $this->addHookAfter( 'Pages::saved(some_checkbox_field=1, status<' . Page::statusTrash . ')', $this, 'hookPageSaved', [ 'priority' => 200 ] ); But this did not work ... Update: This didn't work, because I had a non-standard checkbox via the module CheckboxReversed, so I should have used the selector some_checkbox_field=0. With a default checkbox, the code examples work perfectly.