Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 12/13/2018 in all areas

  1. BitPoet is right but there is a subtlety. Actually you do not need to implement ConfigurableModule because when you use a MyModuleConfig.php along the module file, this new class extend the ModuleConfig class and thus you don't need to implements the ConfigurableModule or other configuration-specific code ! Your module IS configurable at that point. So regarding your fields configuration, it should work and if is not loading, I bet that a uninstall of the module and a Modules > Refresh and/or removing File Compiled/cache then re-installing the module will do the trick. Enjoy ?‍? !
    6 points
  2. I've been working with ProcessWire for a while now, and I've noticed that using Composer to manage dependencies and autoload external libraries isn't as prevalent in ProcessWire development as in other areas of PHP programming. I started out by using the default setup recommend in this blogpost. However, one major problem I have with this approach is that all external dependencies live in the webroot (the directory the server points to), which is unfavourable from a security standpoint and, in my opinion, just feels a bit messy. In this tutorial, I want to go through a quick setup of Composer and ProcessWire that keeps the dependencies, all custom-written code and other source material outside of the webroot, and makes full usage of the Composer autoloader. This setup is pretty basic, so this tutorial is probably more useful to beginners (this is why I'll also include some general information on Composer), but hopefully everyone can take something away from this for their personal workflow. Site structure after setup This is what the directory structure can look like after the setup: . ├── composer.json ├── composer.lock ├── node_modules │ └── ... ├── public │ ├── index.php │ ├── site │ ├── wire │ └── ... ├── packacke-lock.json ├── package.json ├── sass │ ├── main.scss │ ├── _variables.scss │ └── ... ├── src │ ├── ContentBag.php │ └── ... └── vendor ├── autoload.php ├── composer ├── league ├── symfony └── ... As mentioned, the main point of this setup is to keep all external libraries, all other custom source code and resources out of the webroot. That includes Composer's vendor folder, your node_modules and JavaScript source folder if you are compiling JavaScript with webpack or something similar and including external scripts via NPM, or your CSS preprocessor files if you are using SASS or LESS. In this setup, the public directory acts as the webroot (the directory that is used as the entry point by the server, DocumentRoot in the Apache configuration). So all other files and directories in the mysite folder aren't accessible over the web, even if something goes wrong. One caveat of this setup is that it's not possible to install ProcessWire modules through Composer using the PW Module Installer (see Blogpost above), but that's just a minor inconvenience in my experience. Installation You'll need to have composer installed on your system for this. Installation guides can be found on getcomposer.org. First, open up your shell and navigate to the mysite folder. $ cd /path/to/mysite/ Now, we'll initialize a new Composer project: $ composer init The CLI will ask some questions about your projects. Some hints if you are unsure how to answer the prompts: Package names are in the format <vendor>/<project>, where vendor is your developer handle. I use my Github account, so I'll put moritzlost/mysite (all lowercase). Project type is project if you are creating a website. Author should be in the format Name <email>. Minimum Stability: I prefer stable, this way you only get stable versions of dependencies. License will be proprietary unless you plan on sharing your code under a FOSS license. Answer no to the interactive dependencies prompts. This creates the composer.json file, which will be used to keep track of your dependencies. For now, you only need to run the composer install command to initialize the vendor directory and the autoloader: $ composer install Now it's time to download and install ProcessWire into the public directory: $ git clone https://github.com/processwire/processwire public If you don't use git, you can also download ProcessWire manually. I like to clean up the directory after that: $ cd public $ rm -r .git .gitattributes .gitignore CONTRIBUTING.md LICENSE.TXT README.md Now, setup your development server to point to the /path/to/mysite/public/ directory (mind the public/ at the end!) and install ProcessWire normally. Including & using the autoloader With ProcessWire installed, we need to include the composer autoloader. If you check ProcessWire's index.php file, you'll see that it tries to include the autoloader if present. However, this assumes the vendor folder is inside the webroot, so it won't work in our case. One good place to include the autoloader is using a site hook file. We need the autoloader as early as possible, so we'll use init.php: EDIT: As @horst pointed out, it's much better to put this code inside the config.php file instead, as the autoloader will be included much earlier: // public/site/config.php <?php namespace Processwire; require '../../vendor/autoload.php'; The following also doesn't apply when including the autoloader in the config-file. This has one caveat: Since this file is executed by ProcessWire after all modules had their init methods called, the autoloader will not be available in those. I haven't come across a case where I needed it this early so far; however, if you really need to include the autoloader earlier than that, you could just edit the lines in the index.php file linked above to include the correct autoloader path. In this case, make sure not to overwrite this when you update the core! Now we can finally include external libraries and use them in our code without hassle! I'll give you an example. For one project, I needed to parse URLs and check some properties of the path, host et c. I could use parse_url, however that has a couple of downsides (specifically, it doesn't throw exceptions, but just fails silently). Since I didn't want to write a huge error-prone regex myself, I looked for a package that would help me out. I decided to use this URI parser, since it's included in the PHP League directory, which generally stands for high quality. First, install the dependency (from the project root, the folder your composer.json file lives in): $ composer require league/uri-parser This will download the package into your vendor directory and refresh the autoloader. Now you can just use the package in your own code, and composer will autoload the required class files: // public/site/templates/basic-page.php <?php namespace Processwire; use \League\Uri\Parser; // ... if ($url = $page->get('url')) { $parser = new Parser(); $parsed_url = $parser->parse($url); // do stuff with $parsed_url ... } Wiring up custom classes and code Another topic that I find really useful but often gets overlooked in Composer tutorials is the ability to wire up your own namespace to a folder. So if you want to write some object-oriented code outside of your template files, this gives you an easy way to autoload those using Composer as well. If you look at the tree above, you'll see there's a src/ directory inside the project root, and a ContentBag.php file inside. I want to connect classes in this directory with a custom namespace to be able to have them autoloaded when I use them in my templates. To do this, you need to edit your composer.json file: { "name": "moritzlost/mysite", "type": "project", "license": "proprietary", "authors": [ { "name": "Moritz L'Hoest", "email": "info@herebedragons.world" } ], "minimum-stability": "stable", "require": {}, "autoload": { "psr-4": { "MoritzLost\\MySite\\": "src/" } } } Most of this stuff was added during initialization, for now take note of the autoload information. The syntax is a bit tricky, since you have to escape the namespace seperator (backslash) with another backslash (see the documentation for more information). Also note the PSR-4 key, since that's the standard I use to namespace my classes. The line "MoritzLost\\MySite\\": "src/" tells Composer to look for classes under the namespace \MoritzLost\MySite\ in the src/ directory in my project root. After adding the autoload information, you have to tell composer to refresh the autoloader information: $ composer dump-autoload Now I'm ready to use my classes in my templates. So, if I have this file: // src/ContentBag.php <?php namespace MoritzLost\MySite; class ContentBag { // class stuff } I can now use the ContentBag class freely in my templates without having to include those files manually: // public/site/templates/home.php <?php namespace Processwire; use MoritzLost\MySite\ContentBag; $contentbag = new ContentBag(); // do stuff with contentbag ... Awesome! By the way, in PSR-4, sub-namespaces correspond to folders, so I can put the class MoritzLost\MySite\Stuff\SomeStuff in src/Stuff/SomeStuff.php and it will get autoloaded as well. If you have a lot of classes, you can group them this way. Conclusion With this setup, you are following secure practices and have much flexibility over what you want to include in your project. For example, you can just as well initialize a JavaScript project by typing npm init in the project root. You can also start tracking the source code of your project inside your src/ directory independently of the ProcessWire installation. All in all, you have good seperation of concerns between ProcessWire, external dependencies, your templates and your OOP-code, as well as another level of security should your Server or CGI-handler ever go AWOL. You can also build upon this approach. For example, it's good practice to keep credentials for your database outside the webroot. So you could modify the public/site/config.php file to include a config or .env file in your project root and read the database credentials from there. Anyway, that's the setup I came up with. I'm sure it's not perfect yet; also this tutorial is probably missing some information or isn't detailed enough in some areas depending on your level of experience. Feel free to ask for clarification, and to point out the things I got wrong. I like to learn as well ? Thanks for making it all the way to the bottom. Cheers!
    2 points
  3. @MoritzLost regarding earliest include of the autoloader, I think the site config.php is the right place. It is parsed / executed before modules, but it get not overwritten with core updates. ?
    2 points
  4. Also, if you're going to use a separate config.php file, I think it's worth considering the $config = array() approach seen here: https://github.com/ryancramerdesign/Helloworld/blob/master/Helloworld.config.php
    2 points
  5. Your ProcessGoodNews module needs to tell PW that it is configurable by having "implements ConfigurableModule" in the class declaration.
    2 points
  6. I finally started a Cheatsheet for ProcessWire2.1+ Now it's also on processwire.com (auto fetching it from git) http://www.processwi.../api/cheatsheet The github project page: http://somatonic.git...WireCheatsheet/ And there's the git repository: https://github.com/s...sWireCheatsheet I'll continue to add or remove things as times goes by. At some point this will get converted to a PW App. 02.06.2012: - added with $input->urlSegments - added support for GET param in url to &filter and set &advanced - added support for hash in param to filter section 06.02.2012: - updated urlSegment($n) description to avoid confusion - remove some of the alternative syntax 17.12.2011: - added new section "Files" to the sheet - minor structuring of some advanced entries 08.12.2011: - added fix to menu when scrolling - moved some entries to advanced mode - added toggle button on sections - minor changes 04.12.2011: - some restructuring, adds and removes - minor tweaks overall, typos, ordering - added "advanced" mode 27.11.2011: - Added index collumn on left side - You can now toggle sections using the index - Also toggle show/hide all description of a category when clicking on blue titles. - It resets all if you click in the table somewhere (in white space) ADVANCED mode: Mainly it started with only "System Configurations" being advanced, but I added many of the more advanced functions overall. I don't know if it really is the thing to go, but I thought why not try to have very simple and basic version so it would fit on a matchbox . So they're my guess on to what would be the more advanced stuff, and I had kinda hard time to decide what to do and how. After long back and forth I decided to just give it a go and see what people think. Filter I noticed that in mozilla, the live search filtering wasn't working after the changes i've done to it. I figured mozilla has no innerText, which is very practical to get content of a node but not subnodes. I had to use textContent, which returns all text including subnodes, so the search filter doesn't work as good as in other Browsers. May I find a way to work around it. *Found that restructuring the markup was the only way to solve this problem. It should also now work much better in FF for the live search. --- Bug reports, feedback and suggestions are always welcome. Hope you like it!
    1 point
  7. Hi all, I have posted this in the VIP support forum of Padloper as well. Some of you do not have access to that board so posting here as well. Hopefully it doesn't count as spamming?! In June 2018, Antti announced that he was looking for a new product owner for Padloper. Sometime after, I had a fruitful discussion with him about my vision for the project if I was to take over. We agreed that commitment, motivation and a concrete plan were all important ingredients for the continued success of Padloper. I would like to officially announce that I am now the product owner and lead developer of Padloper. For those who may not know, I am the author and maintainer of several ProcessWire modules, both free and commercial. I am also a moderator in the ProcessWire forums. I would like to share with you a number of things regarding what’s going to happen next. This will be a long read. First, I would like to thank Antti for developing a great product. A lot of man-hours, dedication, passion and love has gone into making Padloper what it is today. Secondly, I would like to thank all users of Padloper. A great product is nothing without active users utilising it, putting it to the test, reporting bugs (even offering possible solutions) and proposing new features. So, thank you for helping make Padloper great! Support Thousands of hours have gone into developing Padloper. Although the code is well-written and easy to follow, Padloper is a big application with many moving parts. As such, it will take some time before I can fully grasp its inner workings. To make this transition as smooth as possible, Antti will help me with support for Padloper for some time. Currently, Padloper has a dedicated support forum. This is an arrangement between Ryan and Antti. The support forum works great as it allows the opening of multiple support threads to cover different issues. I have yet to speak to Ryan whether this arrangement can continue. However, given that I have other pro modules that I support in the open forums, it is unlikely that I will be requesting Ryan to let Padloper’s dedicated forum carry forth. A dedicated forum for one of my pro modules and open forums for my other pro modules will lead to confusion and questions from users of those other modules. Hence, Padloper support in the forums will move to the open forums. The disadvantage here is obviously the fact that support will be offered in one single (and maybe massive) support thread. To get around a ‘single thread support forum’, I am thinking of developing a simple online support queue system for all my modules. Meanwhile, support will continue in a new single thread and via email. Roadmap This list is neither exhaustive nor cast in stone. Its aim is to give an overview of my plans for Padloper. · Padloper 2 – a new major release · New backend for Padloper · Optional pro frontend module for Padloper · Documentation · New payment modules Let’s talk a bit about this list. Padloper 2 Release Padloper 2 will be a major release that incorporates a new, central backend shop for Padloper. This will be a new process module that pulls from the existing parts of Padloper (data models, etc) into one interface (more on this below). This version will also be extensible in the frontend, allowing for the plugging in of a new, optional, commercial frontend shop (full featured shop profile). Padloper 2 will not support the current ‘any page can be a product’ paradigm. Technically, products will still be pages. However, all products will utilise the same Padloper template. These will be invisible to the shop users themselves (e.g., hidden in admin tree). Only superusers will have full control of the Padloper system stuff. Support The current Padloper will continue to be supported until the new Padloper 2 is released. New features will be included in Padloper 2 only. Once Padloper 2 is released, legacy Padloper will only receive security fixes. All other support will cease. Upgrade There will be no upgrade path from the current Padloper to Padloper 2. Although their underlying architecture is the same, making sure that everything works in different setups and environments will be time consuming. However, for those who really need to migrate, if time allows and for an agreed fee, I could develop a custom script for the migration. Backend A new backend interface will be the major visual difference between the existing Padloper and Padloper 2. It goes beyond visual differences though. The new backend will be the single gateway for managing all shop-related features, both current and new ones. The backend will unify and include: · Easily add shop products. · Ability to add as little or as many custom fields to products as required (title, SKU, price, discount field, image/photo, description, categories, tags, etc). · Discounts manager (including auto start/expire discount codes). · Customers manager. · Invoices manager. · Taxes management. · Payment gateways manager. · Improved digital products management. · Stock management. · Manual order creation. · Graphical sales report. · Customer support. · Access-controlled shop editors/staff. · Dashboard for shop metrics. · Shop settings. · Product variations. · Import/export products as CSV or JSON. · Products search/filter. · Etc. Users will be able to turn off backend features that they do not need. This will enable a more streamlined experience for users. I plan to release Padloper 2 within 4 - 6 months, hopefully sooner. This is a major undertaking, hence the timescale. Please note that the first release of Padloper 2 will not include all of the above planned features. The idea is to build incrementally, adding new features in minor updates, focusing on stability, usability and security. Frontend Past requests have included the development of a full featured frontend shop. This is planned for Padloper 2. However, this will be an optional pro module priced separately from Padloper itself. The ability to build own frontend shops using Padloper API will still continue. For those who want a plug-n-play solution, this frontend shop will come in handy. The frontend shop profile will feature an ajax-powered shopping cart and a customisable ready-to-go theme. Pricing Model There are no plans to change the current prices of the 3 Padloper licences (Single, Developer and Agency). However, in order to continue to provide Padloper as a stable product with great features, it is also important that it remains a competitive and financially sustainable project. In order for this to happen and to also bring Padloper in line with my existing pro modules, the pricing model itself has to change. Starting from Padloper 2, the pricing model will shift to an ‘annual subscription’ model rather than the current ‘lifetime licence model’. I am fully aware that there are different opinions for and against annual subscriptions. However, I believe that this model is the most equitable approach that suits both the developer and the clients. The annual subscription will allow users (licence holders) to get 12 months of free VIP support for Padloper as well as future updates available within that time period. After the 12 months, users will be able to renew (online) their subscription at a discounted cost (worked as a fraction of the full purchase price) for a further 12 months (perpetually). Users will be able to continue to use Padloper for life even if they don’t renew their subscriptions. Upgrading current licences to Padloper 2 will be a paid upgrade. Current users of Padloper will get an attractive discount. This will be a time-limited offer (maybe a couple of months) that will start with the release of Padloper 2. New customers will pay the full price for Padloper 2. I hope the planned features are reason enough for you to consider upgrading to Padloper 2. Payment Modules I will be taking over as the maintainer and lead developer of the existing payment gateways (Payment base class, PayPal and Stripe). New payment modules are also planned. Payment modules will continue to be free. However, only ProcessWire 3+ support will be provided going forward. Padloper Domain and Future Downloads I have also taken charge of the Padloper domain. Within the next 12 months, purchase and download of Padloper will shift to processwireshop.pw. Please note that this is not the official shop for ProcessWire! It just bears a name that reflects its product offerings ?. Eventually, traffic to padloper.pw will redirect to processwireshop.pw. Feedback I would love to hear your thoughts about the upcoming changes and any feature requests you might have for Padloper 2. Whilst I cannot guarantee that any request will be implemented, I can promise that I will thoughtfully consider all feedback. Thanks for reading and thank you for supporting Padloper! kongondo
    1 point
  8. Something that I found useful recently... Users can type a date/time directly into a Datetime field, which can often be faster than using the separate controls in the datetime picker. But the problem is that there's nothing built into the Datetime inputfield to let users know what the expected input format is for the date/time. You could enter the input format in the description or notes for the field, but you'd have to do this separately for every Datetime field and remember to update it if the input format changes for any reason. Instead, you can use a hook to automatically show the current input format in the notes for all Datetime fields: $wire->addHookBefore('InputfieldDatetime::render', function(HookEvent $event) { /* @var InputfieldDatetime $inputfield */ $inputfield = $event->object; $datetime_input_format = $inputfield->dateInputFormat; if($inputfield->timeInputFormat) $datetime_input_format .= ' ' . $inputfield->timeInputFormat; $ts = strtotime('2016-04-08 5:10:02 PM'); $inputfield->notes = 'Input format: ' . date($datetime_input_format, $ts); }); Or as the title tooltip if you prefer (you have to add the title to wrapper because a title on the input itself gets wiped out by the JS datepicker): $wire->addHookBefore('InputfieldDatetime::render', function(HookEvent $event) { /* @var InputfieldDatetime $inputfield */ $inputfield = $event->object; $datetime_input_format = $inputfield->dateInputFormat; if($inputfield->timeInputFormat) $datetime_input_format .= ' ' . $inputfield->timeInputFormat; $ts = strtotime('2016-04-08 5:10:02 PM'); $inputfield->wrapAttr('title', 'Input format: ' . date($datetime_input_format, $ts)); });
    1 point
  9. Or change it in the database - via the link to Adminer in the RequestInfo panel in Tracy is a nice shortcut, but however you get there is fine.
    1 point
  10. In admin.php file : /** * Hook : * Add FieldtypeDecimal to compatible fieldtypes of * a FieldtypeFloat when a superuser need to change the type * of a float field. * * https://modules.processwire.com/modules/fieldtype-decimal/ * https://processwire.com/talk/topic/7542-development-fieldtypefloat-fieldtypedecimal/ * */ $wire->addHookAfter('FieldtypeFloat::getCompatibleFieldtypes', function($event) { if(!$this->modules->isInstalled('FieldtypeDecimal') || !$this->user->isSuperuser()) return; $return = $event->return; $return->set('FieldtypeDecimal', $this->modules->get('FieldtypeDecimal')); $event->return = $return; });
    1 point
  11. @bernhard @LostKobrakai Just adding my two cents here ... I think if we're talking about writing site-specific modules or code, both options are equally valid and it comes down to preference. I try to write my site-specific functionality in general classes (not extending the Module class) and wire them up in my templates; in this case, it's just less work to connect the namespace through composer than to set up a module and add the namespace manually through the classloader. But really, for code that won't be used anywhere else it doesn't really matter. For reusable code or shareable modules I guess it depends on how closely it integrates with ProcessWire; i.e. my Textformatter module is built as a Processwire module, since it can't be used outside of Processwire anyway. But I'm also working on a collection of utility classes for my personal workflows (based on my markup generation tutorials), and most of those could be used in another context, so in this case I'm building it as a normal composer package, not as a ProcessWire module. One usecase for the Composer autoloader for me is this module: It's not available on any public repository or the module directory, but I can still manually clone it into my project from my private repo and just connect the namespace through Composer. In this case it would definitely be more work to write a wrapper module around it, so for that it's a useful technique. Thanks @horst, no idea why that never crossed my mind ? It's much better indeed, I've edited the tutorial accordingly! I don't think that will work in this specific setup though, since the custom installer mentioned in that blogpost just returns "site/modules/..." as the install path, which isn't correct if your composer.json lives one directory above. Though it would be trivial to fork it and just add the public/ part there ...
    1 point
  12. Minor, but useful update just committed. I noticed that the Console panel didn't have access to custom properties/methods added via hooks in other modules if they were added in ready() vs init(). For example, in the MarkupSEO module when trying to do this, I got null returned. d($page->seo); Anyway, this now works as expected and returns the "seo" property object. Hopefully you guys will find it useful also. If you grab the latest fork of the MarkupSEO module (https://github.com/adrianbj/MarkupSEO/tree/various-fixes-enhancements) you'll also be able to make that call in the Console panel when editing a page in the backend as well as the frontend page view.
    1 point
  13. For some reason, no. But clicking the "clear compiled files" did the trick (at the very bottom - I often overlook it).
    1 point
  14. That's right, and it's something that slipped past me somehow (looking into modules.php, both a MyModuleConfig.php and a MyModule.config.php should automagically make the module configurable). Thus, my bet is on a caching issue too, and it makes sense that adding an external module config without changing the original module file goes unnoticed by PW's module cache. Incrementing the version of MyModule and refreshing the modules should work too in that case.
    1 point
  15. For those who wonder how they can have a module with the third party PHP library managed by Composer, see https://processwire.com/blog/posts/composer-google-calendars-and-processwire/ Also, here is the issue that talks about making Composer's vendor directory location configurable and possibly blocking the vendor/ folder via .htaccess: https://github.com/processwire/processwire-requests/issues/191
    1 point
  16. For composer itself: interoperability and a far bigger ecosystem. For wrapping packages into pw modules: Please don't wrap packages for the sake of wrapping them. It's useful if you provide additional features like configuration through the modules or deeper integration in processwire classes, but that's work and needs to be maintained on top of the package by itself. The only backdraw a plain composer package has on top of a pw module without additional features, is that it can't be installed via the backend, but you need to use the composer cli (and that's more a restriction of composer than of pw). The same is actually also true for the few pw modules which install composer packages. Another problem of wrapping packages is that you cannot get updates without the wrapping module being updated. There is also lot's of tooling like checking for security issues around composer. For anyone not just doing php as a hobby I don't see a reason not to use composer just like nobody uses javascript without npm anymore for any serious work.
    1 point
  17. @adrian thx, I try your suggestion with AdminAction module
    1 point
  18. I understand now what you are trying to achieve. try that : $mypage= $pages->get(1036); $wire->addHookBefore('InputfieldPage::render', function($event) use(&$mypage) { if($event->object->name !== 'job_waehlen') return; $inputfield = $event->object; $selectfield = $inputfield->getInputField(); $selectfield->addOption($mypage->id, $mypage->title, array('selected' => 'selected')); });
    1 point
  19. Thx @MoritzLost! Could you please explain the benefit of using composer compared to packing things into a pw module?
    1 point
  20. And a fourth: $this->wire->pages I prefer this version because you don't need to activate functionsapi (and the functions api should not be used in module development), it is multi instance proof and I get IntelliSense in my IDE Don't know which one is the best in terms of performance...
    1 point
  21. That's what I was refering to. Afaik /vendor is not blocked by default just because there are packages out there containing assets, which need to be web-accessable. I'd personally also lean to just block it.
    1 point
  22. Not really, 'regular'. Have a look at this post. It is old but still relevant (see module prefixes):
    1 point
  23. Would you mind pinging Ryan on that issue referencing my last comment https://github.com/processwire/processwire-issues/issues/480#issuecomment-390819243 ? Thank you!
    1 point
  24. @dreerr - I have exactly the same issue as you on Safari. I have mentioned it towards the end of this discussion: https://github.com/processwire/processwire-issues/issues/480 Basically there still needs to be work done on the UiKit layout. Perhaps you could add a comment there to get Ryan's attention again?
    1 point
  25. @LostKobrakai Thanks for the clarifications! As for the PHP read access, I'm more worried about remote code execution through undiscovered vulnerabilities in external packages (or an attacker gaining write access to a package that gets included through the dependency chain, like we've seen with the event-stream debacle recently). If a PHP file with such a vulnerability lives inside the webroot (especially if it's in a "standard" path like /vendor/vulnerable-package/...), this could give an attacker access to the entire system. Granted, direct access can be blocked in the .htaccess or something like that, but for me it's just one less thing to worry about. Though I'm admittedly a bit paranoid ? ProcessWire's classloader is certainly a good option as well, I just use the composer autoloader because I need to set up Composer anyway for most projects, I guess it comes down to preference. For a shared module or site profile I'd definitely go with the ProcessWire classloader!
    1 point
  26. CKEditor is a nasty beast when it comes to configuring it, but I will try to help ? First things first, how to configure it: https://github.com/processwire/processwire/blob/dev/wire/modules/Inputfield/InputfieldCKEditor/README.md#custom-editor-css-file You probably did this but to make things clear: the field's type is Textarea, while the inputfield's type is CKEditor. So far so good ? On the Details tab: content type is recommended to be Markup/HTML and it should be. "Markup/HTML (Content Type)" option can be configured as required, as they do not affect the CSS we are dealing with. The things in question be configured on the Input tab, under the CKEditor settings, so here come the interesting bits. Available core toolbar items are listed there, and as an example, here is what I often use: PWImage, Format, Styles, RemoveFormat, Bold, Italic, NumberedList, BulletedList, PWLink, Unlink, Table, SpecialChar, Sourcedialog Format and Styles are needed to make those dropdowns show up. If you do not have too many CKEditor fields on the edit page then I recommend setting them to "Regular Editor". We have a thread of discussing settings, BTW: https://processwire.com/talk/topic/17862-share-your-ckeditor-settings/ Turning ACF and HTML Purifier on is generally recommended, however, they might make things harder in terms of keeping those HTML bits intact when saving the page. In the case of ACF, you need to deal with "extra allowed content" so that your code actually gets saved as intended. Here are some forum topics to tackle some issues that may arise: https://processwire.com/talk/topic/19519-ckeditor-and-extra-allowed-content/ https://processwire.com/talk/topic/19918-modify-ckeditor-image-markup-via-hook/?do=findComment&amp;comment=172616 https://processwire.com/talk/topic/12773-ckeditor-does-not-reapply-styles/#entry116174 Normally I turn ACF on, but keep HTML Purifier off in some cases, as I usually use "Regular Editor" instead of "Inline" and have trusted users. However, HTML Purifier is good for making sure only valid code is saved, so it is a trade off not to turn it on. When I do use HTML Purifier, then I sometimes temporarily turn it off during development but I make sure to turn in on for the production site, even for trusted users. If you run into troubles, try turning it on and off to see what it changes in the source. Sadly, HTML Purifier is not yet configurable in ProcessWire. You can give this request a thumb's up though: https://github.com/processwire/processwire-requests/issues/226 Setting up Format Tags is self explanatory, usually I use at least the minimum of p;h2;h3;h4;h5 (h1 is always generated by the template file so no need to include it). Extra Allowed Content is very important, normally I use this: p(*)[*]{*};div(*)[*]{*};li(*)[*]{*};ul(*)[*]{*};i(*)[*]{*};tr(*)[*]{*};*[id];*(class); *[id] and *(class) are somewhat redundant as they allow any IDs and any classes while (*)[*] also allow any of those in the case of the element they are applied to. Now we are getting to the bits you are probably concerned with: Custom Editor CSS File (regular mode) - which can be used to style the HTML of content editor itself as opposed to the frontend Custom Editor JS Styles Set - this is the file you need when you want to define styes for the Style toolbar dropdown Custom Config Options - the notes of the field read: these settings can also be set in one of these files (e.g.) ...config.js and ...config-body.js and this is what I normally use. To configure these options properly this is what you need to tripple check: Make sure: you did create the directory /site/modules/InputfieldCKEditor/ and copied the file called mystyles.js from /wire/modules/Inputfield/InputfieldCKEditor/ to its counterpart: /site/modules/InputfieldCKEditor/ Make sure: files in the directory /site/modules/InputfieldCKEditor/ are named exactly as the ones configured in the options. In the case of Custom Editor JS Styles Set, make sure that in the JS file the function parameter reflects the name you defined in the admin. The default is "mystyles", defined this way: mystyles:/site/modules/InputfieldCKEditor/site_styles.js which means that in the JS file you need CKEDITOR.stylesSet.add( 'mystyles', [... but if you want to use a different string, then replace "mystyles" both in the admin's configuration filed and the accompanying JS file, something like: cke_extra:/site/modules/InputfieldCKEditor/my_extra.js and CKEDITOR.stylesSet.add( 'cke_extra', [... Regarding the configuration files themselves, here is an example for config-body.js: CKEDITOR.editorConfig = function (config) { // Define changes to default configuration here. For example: // config.uiColor = '#AADC6E'; //config.enterMode = CKEDITOR.ENTER_BR; // stops new <p> tags from being added, adds <br /> instead. config.protectedSource.push(/<i[a-z0-9\=\'\"_\- ]*><\/i>/g); // needed for empty <i> tags (icons) config.protectedSource.push(/@/g); // needed for empty <i> tags (icons) /* If this one is enabled: * config.allowedContent = true; * then it is not possible to stop adding widht and height to images */ config.disallowedContent = 'img[width,height]'; // to stop adding widht and height to images }; CKEDITOR.dtd.$removeEmpty['i'] = 0; // needed for empty <i> tags (icons) Regarding mystyles:/site/modules/InputfieldCKEditor/mystyles.js here is one approach for UIkit 3: CKEDITOR.stylesSet.add( 'cke_extra', [ { name: 'Normal Paragraph', element: 'p', attributes: {'class': 'site-paragraph'} }, { name: 'Clear runaround', element: 'p', attributes: {'class': 'uk-clearfix'} }, { name: 'Warning Paragraph', element: 'p', attributes: {'class': 'uk-alert-warning', 'data-uk-alert': ''} }, { name: 'Success Paragraph', element: 'p', attributes: {'class': 'uk-alert-success', 'data-uk-alert': ''} }, { name: '1/2 left align', element: 'img', attributes: {'class': 'align_left uk-float-left uk-width-1-2@s site-body-img'} }, { name: '1/2 right align', element: 'img', attributes: {'class': 'align_right uk-float-right uk-width-1-2@s site-body-img'} }, { name: '1/3 left align', element: 'img', attributes: {'class': 'align_left uk-float-left uk-width-1-3 site-body-img'} }, { name: '1/3 right align', element: 'img', attributes: {'class': 'align_right uk-float-right uk-width-1-3 site-body-img'} }, { name: '1/4 left align', element: 'img', attributes: {'class': 'align_left uk-float-left uk-width-1-4 site-body-img'} }, { name: '1/4 right align', element: 'img', attributes: {'class': 'align_right uk-float-right uk-width-1-4 site-body-img'} }, { name: 'center image', element: 'img', attributes: {'class': 'align_center uk-align-center site-body-img'} }, ]); This method above defines classes for the Style toolbar dropdown in a way that more than one class or attribute is applied to the selected element. For example align_left is applied because the default ProcessWire CKEditor class for left align is this (see this post). However, to make sure that in the frontend the same element is also aligned to the left, I also apply uk-float-left uk-width-1-2@s to it. This is just a dead simple approach but you can make it more sophisticated. If you want to turn CKEditor into a WYSIWYG editor then you need do some extra work, because you need to make sure your contents.css defines the classes and styles also used on the fronted. I have not ventured too far in this direction though. Normally I use UIkit 3 on the frontend and not in the admin so I simply mimic the most important subset of the frontend's styles in contents.css. I will need to improve on this practice but only after I have switched from the Reno Admin Theme to Admin Theme UIkit. I hope I cleared up a few things for you. I you want even more tips form others, I recommend using google to search like this: https://www.google.hu/search?q=CKEditor+site%3Aprocesswire.com%2Ftalk&amp;oq=CKEditor
    1 point
  27. I had a quite some trouble getting this to work with the content from a ProFields Table, as this does not work the same as with a Repeater or PageTable. But I am happy to say that treating those fields as a 'file' works, by setting this in the options array. Ie: <?php $finder = new RockFinder("template=template_name,limit=10", ["title", "some_field_name"]); $field = $finder->addField("my_table_field", ["column_name", "other_column"], ["type" => "file"]); $field->seperator = ", ";
    1 point
  28. Just a note here to say that repeater support is now fixed. A big thanks to @PWaddict for help testing these changes.
    1 point
  29. Quoting from the blog post that @Zeka linked to: "At present, you have to tell ProcessWire you want to use the functions API by setting $config->useFunctionsAPI = true; in your /site/config.php file. Though after more testing, we may make it enabled by default in the future. If you don't have that $config property set to true, the functions are still available, but you have to prepend "wire" to them, i.e. the more verbose wirePages() rather than pages()."
    1 point
  30. What do you mean by this? Echo the value of a field or echo a field name? If the latter, spaces are not allowed in field names (neither are hyphens; only underscores). If the former, you can just use these PHP functions strtolower or mb_strtolower (for multibyte support)
    1 point
  31. Hi, you have to assign a page. $wire->addHookAfter('InputfieldPage::processInput', function($event) { if($event->object->name == 'job_waehlen') { bd($event->return->value); // return 1019 (my test id page) $event->return->value = $this->pages->get(1); // will set you parent tree bd($event->return->value); // return 1 (root page) } }); PS: bd() call come from TracyDebugger
    1 point
  32. @Laikmosh I'm not sure, but I think that there is no difference in performance between $pages, wire('pages) and pages(). There is also a third way to access API variables - functions API https://processwire.com/blog/posts/processwire-3.0.39-core-updates/#new-functions-api
    1 point
  33. That's exactly the point. You might regret it. Doing such a complex project without experience is never a good idea.
    1 point
  34. Hello, There are basically three approaches you can choose from: 1. "Styles" dropdown: Make use of CKEditor's "Styles" dropdown, and define the styles the editors must apply to each image: https://processwire.com/talk/topic/19465-ckeditor-styles-dropdown-tips/ https://github.com/ryancramerdesign/ProcessWire/blob/dev/wire/modules/Inputfield/InputfieldCKEditor/README.md#advanced-tips 2. by using Hanna Codes: This approach is not for everyone but very versatile: https://processwire.com/talk/topic/11549-insert-any-html-tag-with-attributes-using-hanna-code/ http://modules.processwire.com/modules/process-hanna-code/ 3. automatically manipulate CKEditor content via custom coding: https://processwire.com/talk/topic/19918-modify-ckeditor-image-markup-via-hook/?do=findComment&amp;comment=172616 http://modules.processwire.com/modules/textformatter-fluid-images/ http://modules.processwire.com/modules/textformatter-make-links/ https://processwire.com/talk/topic/14835-module-textformatter-for-uikit-images/ Hope this helps.
    1 point
  35. Hi Michael Wether it’s a blog, or a news page or a product overview page, the fundamentals are the same. 1. This makes most sense and is a well organized structure. I like to create a page called blog. This is the blog homepage or overview listing a small preview of each blog post. In a sub folder under blog I actually store my blog posts in a sub folder called called posts. This is because within my blog folder I also have pages for tags and categories and archives I want to keep them all orderly. You’re probably not at a point where you want tags and categories but it means in future you have the foundations in place. But even if you started out differently and realized you need to re organize everything further down the road, it’s a trivial thing to make your blog work with a different structure and some small changes to your selector in your template 2 you can display a smaller image with css or look at the image api and specify a width or height etc 3 on your blog article template, create a field for each and then pull this info onto any page you wish wether it’s the blog home or the homepage etc 4 you would have 1 blog post template and every page would be based on this template Sorry this is so general with no actual examples but I’m typing on the phone.
    1 point
  36. Captain Hook ProcessWire Hooks Cheatsheet http://somatonic.github.com/Captain-Hook/ or on processwire.com http://processwire.com/api/hooks/ I created a simple list with a live search for all hookable methods available in the core. All methods prefixed with a "___" (3 underscores) are hookable. Methods can be made hookable by simply adding those ___ to it. ------------------------- I usually don't really need this, but thought it would be good to have an official list for reference. I used Sublime Text2 for searching and dumb a file with a search for " ___" in wire core. From this list I created a html file with a php script and added some fuzzy live search, similar to the API cheatsheet. If you use Sublime Text 2 like me you can simple use Goto Anything command super+p to show a fuzzy search for files. Enter a class name you want to search for. For example "fields" or "process page edit" you will recieve a list of files found in PW. Highlight the file and typ a @ to see the symbol list quickly or select the file and super+r the get the symbol list.
    1 point
  37. Both customized listers and bulk actions are available to you without ListerPro. Just have a look at the core ProcessUsers and PageActions modules. ListerPro just provides the "more than easy to setup" interface for those things. But maybe the basic "set up a new Lister" functionality could really be move to the core Lister in the future, as the Pro Version seems to be getting other unique selling points.
    1 point
  38. What's critical about Lister Pro? The ability to easily save a customized lister, perform bulk actions on results, and have convenient, end-user access to tabular views of large content types that are too cumbersome to manage from within the tree control. This is standard functionality in any CMS worth using, and essential for the vast majority of sites I've built over the last 20 years or so. It's a bit silly, IMO, that you can't do these things with the built-in lister. It feels intentionally crippled solely for the sake of selling the commercial component, a perception we want to avoid. I wouldn't build anything more than the most basic, trivial processwire-powered site without Lister Pro, whereas I could easily do without the other pro modules. I (sometimes) use Form Builder out of convenience, but Lister Pro out of necessity. Mind you, I'm not complaining about the cost, at all. It's entirely reasonable and I'm happy to support development. But if we're talking about the road map for the core, open source project, I most definitely view Lister Pro as essential functionality that absolutely should be part of it. I am intrigued by the idea of "graduating" pro modules to core modules via some process that combines hitting some financial goal with enough general community interest in having specific functionality available in the core. Just my two cents.
    1 point
×
×
  • Create New...