Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 01/18/2019 in all areas

  1. I'd planned on writing up a blog post today and bumping the PW version up to 3.0.125, but working on documentation pages ended up taking up most of the day. My hands are getting a bit tired from all the writing, so I'll keep this post short. ? I'll have a more formal post with more on the 3.0.125 version next week. People have been asking for more information on the various ProcessWire API access methods, as well as more information on the Functions API. I've written up a new documentation page that covers all the details. Though it's become a bit long, so next week I might split off the Functions API part into a separate child page. But for now, this is what I've got—the new documentation page is located here: https://processwire.com/docs/start/api-access/ In addition, the ProcessWire API Explorer module has been updated to support documentation for ProcessWire's procedural functions this week. And as a result, our online API documentation page now covers them all too. I spiffed up the phpdoc on all of them (and in some cases re-wrote the content) in preparation for that. For those that were asking for more documentation on the API functions, this page also has a section dedicated for those. Here's a direct link to our more than 50 procedural functions available in PW that previously didn't have any online documentation: https://processwire.com/api/ref/functions/
    11 points
  2. Yes and no: the page those forms are rendered from isn't actually in the admin area. By default it's a regular page at /form-builder/. This page has a template file of its own, and when you access said page, it figures out the correct form and renders it – making use of some stuff bundled with the core for rendering the form and form fields. Technically you can do that with any module that produces output: just figure out when and where to render it, call a method that returns output, make sure that necessary styles and scripts are loaded, and output the... err, output. If you need to do something based on user actions, implement necessary endpoints with hooks, URL segments, or based on POST/GET data. I'm using something similar in ProcessChangelog for rendering the RSS feed generated by a Process module for front-end users: https://github.com/teppokoivula/ProcessChangelog/blob/master/ProcessChangelogRSS.module#L97:L103. ... but that's a really, really simplified version of it, and perhaps not quite what you're looking for yet. ? AdminBar makes use of the ?modal=1 parameter that Admin supports, in which case header/footer areas are left out of the response. I've used this method for injecting things like profile edit screens into the front-end for registered and logged-in users – though they tend to look a bit off in an iframe, so usually I use an actual modal instead – but it doesn't yet solve the permission issue. ProcessWire's permission system is relatively flexible, but as @bernhard already pointed out, there are always risks involved when you tweak such things ? Not trying to speak for Bernhard, but I believe the idea was to utilise the module architecture, probably Process modules in particular, to easily create front-end-oriented tools, so not really free-for-all editing per se. A booking system might be a good example – you may want to give guests a limited access to create new content or perhaps even edit/delete content based on specific set of rules, but this could also be useful for creating non-editable views. Front-end listers, anyone? ? --- I think that overall this idea has some potential. Not sure to what extent, or how feasible this would be, but it might be worthwhile creating a small proof-of-concept and trying things out. The permission thing is still a huge question mark, though. If I was to build something like this, I'd probably start by looking what ProcessController core class is doing, and how it's used by the Admin itself. Though correct me if I got the whole concept wrong, and this is actually about something different entirely. There may be other ways to use the module system in the front-end as well, but Process modules are basically what the Admin side is made of, so when you say "public backend pages" – well, that's what it sounds like to me ?
    4 points
  3. I am slowly progressing, because I struggled with loading the JSON via AJAX in conjunction with vue.js (which I sadly did not managed yet). And had to get used to vue.js a little bit more. There is a lot of old markup that needs to be refactored, but the module is already working. I optimized and prioritized which information should be shown, and what is additional information, which will be shown with a specific action like clicking a link or hovering over the card. Don't know it excactly yet. Here you can see which module is installed or not installed and have options to install it. Support for quick uninstalling/deactivating modules is coming soon. And in this screenshot you see how it looks if a module can be updated. The layout is still work in progress and not finished yet. Still deciding on icons, colors, etc.
    4 points
  4. The Page Hit Counter module for ProcessWire implements a simple page view counter in backend. Page views of visitors are automatically tracked on defined templates, with monitoring of multiple page views. This gives you a quick overview of how many visitors have read a news or a blog post, for example, without first having to open complex tools such as Google Analytics. This module quickly provides simple information, e.g. for editors. Or, for example, to sort certain news by most page views. For example for "Trending Topics". Works with ProCache and AdBlockers. With a lightweight tracking code of only ~320 bytes (gzipped). And no code changes necessary! In addition GDPR compliant, since no personal data or IP addresses are stored. Only session cookies are stored without information. In addition, there are some options, for example filtering IP addresses (for CronJobs) and filtering bots, spiders and crawlers. You can also configure the lifetime of the session cookies. Repeated page views are not counted during this period. It is also possible to exclude certain roles from tracking. For example, logged in editors who work on a page are not counted as page views. Sort by hits and access page views (hit value) Each trackable template has an additional field called phits. For example, you want to output all news sorted by the number of page views. // It is assumed that the template, e.g. with the name "news", has been configured for tracking. $news = $pages->find("template=news, sort=-phits"); To output the page views of a tracked page, use: echo $page->phits; Example: Reset counter per API $modules->get("PageHitCounter")->resetPageViews("template=whatever", false); Example: Tracking a page hit via API and jQuery If you want to track a template that does not represent a full page to automatically inject a tracking script, you can define allowed API templates in the module that you can track. Below is an example of how you can track a click on news tag using jQuery. This will allow you to find out which keywords are clicked the most. For example, you can sort and display a tag cloud by the number of hits. Suppose your keywords have the template "news_tag". The template "news_tag" was also configured in the Page Hit Counter Module as a trackable API template. Example PHP output of keywords / tags: // Required: the data attribute "data-pid" with the ID of the template to be tracked. echo $pages->find("template=news_tag, sort=-phits")->each("<a href='{url}' class='news_tag' data-pid='{id}'>{title}</a>"); Example Tracking Script with jQuery: /** * Required: Data attribute "data-pid" with the ID of the news tag template * Required: Send the POST request to the URL "location.pathname.replace(/\/?$/, '/') + 'phcv1'" * Required: The POST parameter "pid" with the ID of the template */ $(function(){ if($('a.news_tag').length > 0) { $('a.news_tag').each(function(){ var tPID = $(this).data("pid"); if(tPID) { $(this).on("click", function(){ $.post(location.pathname.replace(/\/?$/, '/') + 'phcv1', {pid: tPID}); }); } }); } }); So simply every click on a tag is counted. Including all checks as for automatic tracking. Like Bot Filtering, Session Lifetime, etc. Notice: Tracking with URL segments If the option "Allow URL Segments" is activated on a template, the hits are only counted if the base URL of the page is called. If you want the hit to be counted even when a segment is requested, you MUST configure the segments in the template configuration. How to do this can be found here. If you use dynamic segments, configure them as RegEx. There is currently no other option. The problem is that the Page Hit Counter hooked into the PageNotFound process. If URL segments are allowed but not defined, a 404 is never triggered. This means that the Page Hit Counter cannot be called. New since 2.0.0: Ignore URL segments If a template has URL segments configured, each hit on a different segment is counted as a new hit. Enable "Ignore URL segments" so that dynamic segments are not counted individually on the base template / page. New since 2.0.0: Use cookieless tracking (Experimental) Enable this option to not use individual cookies for tracking or if you have many different pages you want to track. The limit for cookies is 50 per domain for all cookies on the page. If the option is enabled, PHP session storage is used. Downside: you can't set the lifetime higher than configured in your PHP.ini and the session will be terminated as soon as the browser is closed. Upgrade note for 2.0.0 from previous versions! Version 2.0.0 requires an update in the database schema, so that additionally the date of the last access / hit on the page can be displayed ($page->lastPageHit). To make this possible, you have to do the update via the upgrade module, upload the ZIP itself and do an update directly via the backend AND DO A MODULE REFRESH DIRECTLY AFTER UPLOAD/UPDATE. If you do not do this, you will get an error that a column is missing in the database table. _______________________________________________________ Background: This module is the result of a customer requirement, where the editors are overwhelmed with analytics or no tracking tools were allowed to be used. However, a way had to be found to at least count page views in a simple form for evaluations. Furthermore, by using ProCache, a way had to be found to count views of a page without clearing the cache. _______________________________________________________ Pros Automatic Page View Tracking Lightweight tracking code, only ~320 bytes (gzipped) No code or frontend changes necessary Works with ProCache! Even if no PHP is executed on the cached page, the tracking works Works with browser AdBlockers No cache triggers (for example, ProCache) are triggered. The cache remains persistent GDPR compliant, session-based cookie only, no personal information Filtering of IPs and bots possible Exclude certain roles from tracking Ability to reset Page Views Works with all admin themes Counter database is created as write-optimized InnoDB API to track events for templates that are not viewable No dependencies on libraries, pure VanillaJS (Automatic tracking script) Works in all modern browsers Pages are sortable by hits Cons Only for ProcessWire version 3.0.80 or higher (Requires wireCount()) Only for PHP version 5.6.x or higher No support for Internet Explorer <= version 9 (Because of XMLHttpRequest()) No historical data, just simple summation (Because of GDPR) Segment URLs can only be counted if the segments are defined Planned Features / ToDos API access to hit values Since version 1.2.1 Possibility to sort the pages by hits (Request by @Zeka) Since version 1.2.0 Don't track logged in users with certain roles (Request by @wbmnfktr) Since version 1.1.0 Possibility to reset the counter for certain pages or templates (Request by @wbmnfktr) Since version 1.1.0 Better bot filter Since version 1.1.0 Disable session lifetime, don't store cookies to track every page view (Request by @matjazp) Since version 1.2.1 Option to hide the counter in the page tree (Request by @matjazp) Since version 1.2.1 Option to hide the counter in the page tree on certain templates Since version 1.2.1 API to track events for templates that are not viewable Since version 1.2.2 Cookieless tracking Since version 2.0.0 Show last hit Since version 2.0.0 Ignore URL segments (Request by @bernhard) Since version 2.0.0 Add hookable method after pageview was tracked (Request by @bernhard) Since version 2.0.0 Changelog 2.0.0 Feature request: Add hookable method after pageview was tracked (___pageViewTracked($pageID)) (Requested by @bernhard) Feature request: Ignore URL segments option (Requested by @bernhard) New: Cookieless tracking New: Show date of last hit Update: Botlist Enhancement: Documentation improvement 1.2.7 Feature request: make buildPageListHitCounter-Function public (Requested by @bernhard) 1.2.6 Bug-Fix: Set the counter of a cloned page to 0 Enhancement: The function for resetting counters is now available in the module as a public function to reset counters via own scripts on the API side (Request by @VeiJari) Enhancement: Documentation improvement API reset 1.2.5 Bug-Fix: When counting 404 hits, cookies are no longer set. The session lifetime is deactivated for the 404 page Enhancement: Documentation improvement regarding URL segments 1.2.4 Bug-Fix: Resetting the counters on system pages (e.g. 404) does not work (Reported by wbmnfktr) Bug-Fix: Tracking endpoint is logged as 404 if module "Jumplinks" is installed (Reported by wbmnfktr) Enhancement: Corrected few typos (Merged from Sergio #6 – THX!) 1.2.3 Bug-Fix: Tracking script triggers 404 if pages are configured without slash (#3) Reported by @maxf5 Enhancement: Reduction of the tracking script size if it's gzipped (~320 bytes) Enhancement: Documentation improvement Enhancement: Corrected few typos 1.2.2 New feature: API to track events for templates that are not viewable Enhancement: Documentation improvement 1.2.1 API access to hit values Use $page->phits Bug-Fix: No tracking on welcomepage (Reported by wbmnfktr; Thx to matjazp) Bug-Fix: Tracking script path on subfolders (Reported by matjazp) Bug-Fix: Tracking on pages with status "hidden" Enhancement: Change database engine to InnoDB for phits field Enhancement: Option to disable session lifetime set session lifetime to 0, no cookies Enhancement: Better installation check Enhancement: AJAX Request asyncron Enhancement: Reduction of the tracking script size by ~20% Enhancement: Option to hide the counter in the page tree You can output the counter with the field name "phits" Enhancement: Option to hide the counter in the page tree on certain templates Enhancement: Option for activate general IP validation Enhancement: Reduction of tracking overhead up to ~30ms Enhancement: Better bot list for detection 1.2.0 New feature: Sort pages by hits – New field phits Migrate old counter data to new field 1.1.0 New feature: Exclude tracking of certain roles New feature: Reset Page Views Better bot filter and detection 1.0.0 Initial release Notes By default, the page views are stored as INT in the database. This allows a maximum counter value of 4.2 billion views (4,294,967,295) per page. If you need more, change the type to BIGINT directly in the database. But I recommend to use Google Analytics or similar tools if you have such a large number of users. _______________________________________________________ Download GitHub: ProcessWire Page Hit Counter (Version 2.0.0) PW Module Directory: ProcessWire Page Hit Counter (Version 2.0.0) Install via ProcessWire (Classname): PageHitCounter _______________________________________________________ Update information If you have used version 1.2.1 from the DEV branch, please replace it completely with the new master version. Old stable version Download GitHub: ProcessWire Page Hit Counter (Version 1.2.7)
    3 points
  5. That's not how MarkupPagerNav works. The MarkupPageNav module is useful when you want to stay on one page which is listing summaries from a PageArray of other pages. The pagination is for those summaries, so if with no limit applied a selector would return a PageArray of 20 pages and you wanted to show 4 summaries per page (limit=4) on some overview page then MarkupPagerNav would create 5 links. But you always stay on the overview page - the links in the pager don't take you to the individual pages that the summaries are for. So technically you could create a pager on the Table on Contents page, using a PageArray of child pages with a limit of 1, and then output the whole content of the child page in your foreach loop. But instead I think you want visitors to actually visit those child pages, not just stay on the Table of Contents page. So what you want is a normal menu for the pages in your PageArray. You can create this any way that you like to create menus in your site, but here is an example: <?php $items = $page->siblings(); $next_page = $page->next(); $prev_page = $page->prev(); ?> <!-- Add whatever classes or extra markup you need to this unordered list --> <?php if($items->count > 1): ?> <ul> <?php if($prev_page->id): ?> <li><a href="<?= $prev_page->url ?>">Previous</a></li> <?php endif; ?> <?php foreach($items as $key => $item): ?> <li class="<?= $page === $item ? 'current' : '' ?>"><a href="<?= $item->url ?>"><?= $key + 1 ?></a></li> <?php endforeach; ?> <?php if($next_page->id): ?> <li><a href="<?= $next_page->url ?>">Next</a></li> <?php endif; ?> </ul> <?php endif; ?>
    3 points
  6. Check out Adrian's Page Field Select Creator if you haven't already. It makes setting up Page Reference fields just as fast as setting up Options fields.
    3 points
  7. I don't think RF changes any lower/uppercase. Quickly googling for "case sensitivity table mysql" returns tons of results though, suggesting it may have to do with how mySQL handles case-sensitivity on different OS... just one random example: https://searchdatacenter.techtarget.com/answer/Naming-and-renaming-MySQL-files-for-case-sensitivity
    2 points
  8. In version 1.2.1 (Master) it is now possible. Every trackable template has a field called "phits". You can use this field in selectors. Either to sort: template=news, sort=-phits or as a value selector, for example: template=news, phits>=100 For an output in the frontend, simply access the field with: $page->phits This makes it very easy to output "trending topics", for example. Select news with a date field in a certain period and sort by "phits".
    2 points
  9. This problem has now been fixed in version 1.2.1 (master). Thanks for the report. All in version 1.2.1 (Master) You can now set the session lifetime to 0, which will disable cookies and count each page view Thanks for the bug report, the problem with location.pathname is fixed The problem was in fact the ctype test. Good found, thanks and fixed I have optimized the request a bit, the overhead is reduced I've added an option that lets you hide the counters. By accessing the field "phits" you can make your own output according to your ideas This is correct, only counters are reset which already have a value greater than 0. I have formulated this differently in the descriptions and in the output to make it clearer and more understandable Thanks to @matjazp and @wbmnfktr for testing and reporting. ?
    2 points
  10. Is it a Vue issue or CORS with AJAX in general? https://codepen.io/adrianbj/pen/QzXwGz?editors=0010 If it's just Vue related, I use AXIOS for this stuff: https://vuejs.org/v2/cookbook/using-axios-to-consume-apis.html PS, it's looking great! PPS - why AJAX - given how small the JSON for all the modules is, why not just load everything at once via PW's $http->getJSON()
    2 points
  11. Just verified that this can be made running in combination with @BitPoet's simple language switcher: I've basically added a text field url_domain to the language template and moved the default language detection from _init.php into the updatePath method (so my loop makes much more sense now): public function updatePath($path) { $httpHost = $this->wire('config')->httpHost; $languages = $this->wire('languages'); // Setup default language by domain root foreach($languages as $lang) { if(($lang->url_domain != "") && (strpos($httpHost, $lang->url_domain) > 0)) { $this->user->language = $lang; break; } } This change eliminates most of the other default processing, since the default already set based on the domain name. Throughout the site I'm using localUrl to generate internal link urls, that code was changed to get rid of the language segment in case it is the default for the current domain: public function hookPageLocalUrl(HookEvent $event) { $lang = $this->getLanguage($event->arguments(0)); $config = $this->wire('config'); if(($lang->url_domain != "") && (strpos($config->httpHost, $lang->url_domain) > 0)) // Default for this domain? $event->return = $config->urls->root . ltrim($event->object->path, "/"); else $event->return = $config->urls->root . ltrim($lang->name . $event->object->path, "/"); } The benefit of this is, that languages can be added to the site without the need having an associated domain for each. And it does not break old links on my site, which still have the language in the url. So www.domain.com/pagename and www.domain.de/en/pagename still retrieve the same content and another language may be reached through www.domain.de/fr/pagename or www.domain.com/fr/pagename for example. Edit: Just in case someone wants to see this in action: www.versus-x.com (english) www.versus-x.de (german) www.versus-x.com/de/ (also german) www.versus-x.com/fr/ (french, incomplete, for testing only) www.versus-x.de/fr/ (french, only parts as well)
    2 points
  12. A few more minor bits and pieces... The left-side-only border on the three columns under the home page code samples looks a little off: It would look better if the borders were only on the inside edges of the columns, like the three column example in the footer: I think others have already commented about the blog overview layout. I find this layout confusing to parse because the box alignment is stronger vertically than it is horizontally, which makes me scan the posts top to bottom when actually the order is left to right. Having equal box heights within each row would improve this somewhat but I think there will still be some confusion for readers trying to work out the order. Maybe we should consider an entirely different layout for this page? Also regarding the blue box style - the are some small issues with the little circles on the corners. Sometimes they are stacking behind a neighbouring box so the line goes through the circle instead of behind it. This can be seen in the screenshot above. And perhaps there should be a circle in every corner of each box (it doesn't matter if the circles are doubled-up where two boxes meet) because the visual logic of where the circles are missing doesn't make much sense in some places: Lastly, I spotted a couple of little issues in some code blocks. 1. LSEP character showing here: https://processwire.com/docs/start/templates/ 2. $ variable symbol sometimes gets wrong colour here: https://processwire.com/docs/selectors/
    2 points
  13. For the wiki, there was two issues addressed about that. I will be able to give more infos in the next weeks. But yes, wiki are gone for free private repos on personal accounts. More precisions from the support about Accounts, Private repos and Organization as I tried to make an organization with free private repos but it not worked - of course ?
    2 points
  14. This module provides a way to rapidly generate Page fields and the required templates and pages for use as a drop down select (or any other Page field type). This module will let you create a full page field setup in literally a few seconds To use, run Page Field Select Creator from the Setup Menu Enter a Field Title, eg: Room Types Select Options - These will become the child pages that will populate the page field select options. There are two different options. Option 1. TITLE FIELD ONLY - enter one option per line, eg: Single Double Suite Option 2. MULTIPLE FIELDS - the first line is used for the field names and the first field must be 'Title'. Subsequent lines are the values for the fields, eg: Title, Number of Beds, Number of People, Kitchen Facilities Single, 1, 1, Fridge Only Double, 2, 2, Fridge Only Suite, 3, 6, Full Kitchen Choose the parent where the page tree of options will be created, eg a hidden "Options" parent page Select a "Deference in API as" option depending on your needs Choose the input field type Check whether "Allow new pages to be created from field?" should be enabled. As an example, if you entered "Room Types" as the field title, you would end up with all of the following automatically created: a fully configured page field called: room_types MULTIPLE FIELDS OPTION - 3 additional fields - number_of_beds, number_of_people, kitchen a parent template called: room_types a child template called: room_types_items (with either just a title field, or with the 3 additional fields as well) a parent page called: Room Types a series of child pages named and titled based on the per line entries in the Select Options textarea The templates are configured such that the "room_types_items" child template can only have the main "room_types" template as a parent, and vice versa. Then all you have to do is add the newly created page field to any template you want and you're ready to go! You can grab it from: Modules directory: http://modules.processwire.com/modules/process-page-field-select-creator/ Github: https://github.com/adrianbj/ProcessPageFieldSelectCreator
    1 point
  15. *** Thank you. The more I played with it the more I thought, "you know... this is for search results...I don't think this is the right application for the pager... so I went on to do the next and previous page thing - less terrific than yours so I will be happy to try your code as mine is a little thin. But thank you for that. Suspicions confirmed. ?
    1 point
  16. @rastographics, it looks like you're missing a semicolon (";") at the end of the line starting with "$f->description". Or was the screenshot cut off early? ?
    1 point
  17. Info: All new features and download link will be updated in the first post.
    1 point
  18. I think let's stick to convention. ProcessWire has always used installed ?. For me, it means the module is installed in the ProcessWire system. A module that is present on the disk but not yet installed just means it is not yet part of the ProcessWire system. Of course. My point was not that they should not be there, but they should probably be in their own tab, just to make things obvious ?. ??
    1 point
  19. I recommend @arjen's fork instead: https://github.com/arjenblokzijl/FieldtypeDecimal as @sforsman seems to have abandoned his module.
    1 point
  20. Changelog The changelog can now be found in the module directory itself, see CHANGELOG.md.
    1 point
  21. @MoritzLost Great tutorial I often use Repeater Matrix field with an added Fieldset Page containing the styling options for that section. FS page means it's easy to add a single field to different templates. Like you, I only give the client what options they need rather than the complete set. In the example below, the HTML theme is Canvas which is based on Bootstrap.
    1 point
  22. Sure, i don't see any reason I couldn't maintain the module; I think it is basically stable and we'd just need to all contribute our changes, test it and then it should be good to go... I'll try and get that setup soon..
    1 point
  23. Correction to this: in the blog post Ryan mentions the wire-prefixed Functions API methods and explains that they have the benefit of being always available regardless of config settings (essentially the same thing that the comments in the FunctionsWireAPI.php file say) – but there is a comment to the blog post in which he mentions that these are actually "for an internal core purpose". @ryan, this might be one of the things that should be clarified somewhere: if wire-versions of the Functions API methods are indeed not intended for public use, it should probably be mentioned somewhere (other than a single comment to the Functions API announcement blog post). If one reads the blog post and doesn't check all the comments, or checks the code / code comments directly (which is a common thing to do in our context), this is currently not obvious.
    1 point
  24. Hi Moritz, big thanks for this one too! ? I use a similar setup, but with page references instead of option fields.
    1 point
  25. Good suggestions. ? Both functionalities are implemented in the current Dev branch. You can test them here: https://github.com/FlipZoomMedia/PageHitCounter/tree/dev
    1 point
  26. I always do a quick install on unknown servers with the blank site profile, pull in the modules for Diagnostics and the ProcessDatabaseBackup, do a proper check of server, database (charset collations etc.), filesystem, PHP, image support, etc, and if all is well or changed to be well, I install the initial database dump and switch to the site profile. The times before I switched to that approach, I several times run into issues that could be ommitted with my current approach, and it took me much more time to find out what was not setup right or missing. - Sure, if you already know the server you deploy to, it can be done without the initial install and diagnostics step. But also on a known server, someone may set the wrong database charset, wrong file access rights, or bind a account to the wrong PHP version, or what ever. Do a fresh install and check with diagnostics modules all together takes 10 minutes max., to see if everything is as it should be. ?
    1 point
  27. Hi all! Happy New Year ? I recently rebuilt the website for classroombookings - my open-source room booking system for schools - using PW ? classroombookings.com I started the project itself way back in about 2006, when I was working in a school and needed a solution. Over the years I haven't made that many changes to it - mostly due to lack of time - but it has a modest userbase. Fast-forward to late 2018 when it required a major update to support PHP 7, fix some issues, and I also launch a hosted service. The website serves marketing, documentation and download/release functions for the project and I think PW is ideal for it. In the spirit of open source, the code for the website is also available on GitHub for anyone who wants to poke around and see my approach to PW web builds. The site is pretty standard, the only 'custom' bit is the releases section, which it pulls from GitHub using their API and creates/updates pages (Releases module). The frontend uses the Spectre CSS framework, and this is the first site I've built using it. Modules: AdminTemplateColumns ProcessDateArchiver SettingsFactory TextformatterHannaCode
    1 point
  28. Well said @LostKobrakai! Agreed 100% IMHO that depends a lot on your skills. For me it took very long to understand how the backend works and what all those (process)modules do and how all this plays together. That's why I wrote my tutorial blog post (which by the way took also very long, so I perfectly understand that ryan does not have this time - especially if it is correct that CMF users are not the target audience (and that's what I meant in my short statement above where I said that I think that ryan does not really care). And even if you are highly skilled it would be a lot more efficient to read good docs than to read good code. I liked to read @Robin S answer and I'm sure it was not meant bad ? I agree with you that it would be a lot easier if we had proper tutorials (not just api docs and example modules) about all the backend stuff. I've mentioned several times that I think that the community management and teamwork on the project could be improved. It feels like ryan does all the work and if he has no time for something, it's just not done... On the other hand writing my guest blog post was easy: I just asked ryan if he was interested and I got a login and started writing... It's for sure not a perfect documentation about the backend, but it's a first step and I invite others to follow ?
    1 point
  29. I think you both have valid points. If ProcessWire wants to get more exposure and usage (…more devs creating quality modules) there are lot's of places to advance or update documentation or educate better. Especially module development can easily be daunting to newcomers as it's basically "do what you want" besides some conventions around config / module info / process module callbacks. There could also be more (UI) components to make processwire modules really feel like integrated into the backend. Currently this is mostly on the module developer which is neither efficient nor works really well. Besides the InputfieldWrapper and MarkupAdminDataTable component I feel like there's a severe lack of consistency in the ProcessWire UI a.k.a. truely reusable UI components to be used by module devs. One can certainly do a lot with just those two, but that depends on the module. It should be perfectly fine to talk about such shortcomings. Especially if it's the experience of someone new here it should be a clear sign about places to improve. What we should be aware though is that we're still talking about oss and resources are sparse. Ryan will do what he can in the places he thinks are most important. This might not necessarily align with what other people think is most important. E.g. from my years in this community I feel like Ryan sees ProcessWire much less as a CMF than many people use it as. So the developer turning the admin experience around by 180 degrees is not really the primary target group. This explains any lack of grand documentation in this place and maybe the quite a few modules needing to fill in the gaps.
    1 point
  30. you might be misunderstanding this. Context help for templates means you need to add a template select field to the page holding the content to be shown on that template. Notice how you are missing that whole setting - you need the fieldtype, then the field and add it to the doc page template, then select the template where to show the doc.
    1 point
  31. you need 1 process page for each displayable doc page.
    1 point
  32. @jmartsch (1) did you select a page to display and is the field containing the content populated on that selected page? yes, it is, but you'll need the other module, called ContextHelpTemplate, and that module can work with PD https://github.com/outflux3/ContextHelpTemplate
    1 point
  33. Using ProcessWire's in-built multi-site support (option #1 here), is it possible to bootstrap the various sites? To bootstrap ProcessWire, the only requirement is to include /path/to/processwire/index.php/. In option #1, there is only one index.php. So, including index.php defaults to bootstrapping the main site (i.e. the site at /site/. Is it possible to bootstrap the other sites, i.e. site-dogs, site-cats, site-birds, etc? I've searched the forums but nothing relevant comes up. Thanks.
    1 point
  34. A cheap rip-off of LanguageSupportPageNames that adds support for prefixed urls, localUrl and localHttpUrl: <?php /** * Adds simple support for URL paths prefixed by language name. * * Proof-of-concept. * * Most of the actual code is stolen from LanguageSupportPageNames. * Adds the same localUrl and localHttpUrl methods to page objects. * */ class LanguageSupportPath extends Wire implements Module { public static function getModuleInfo() { return array( "title" => __("Support for Language Path"), "summary" => __("Adds simple support for URL paths prefixed by language name"), "version" => "0.0.3", "autoload" => true, "requires" => array( "LanguageSupport" ) ); } public function init() { $this->addHookBefore("ProcessPageView::execute", $this, "hookProcessPageViewExecute"); } public function ready() { $this->addHook('Page::localUrl', $this, 'hookPageLocalUrl'); $this->addHook('Page::localHttpUrl', $this, 'hookPageLocalHttpUrl'); } /** * Hook in before ProcesssPageView::execute to capture and modify $_GET[it] as needed * */ public function hookProcessPageViewExecute(HookEvent $event) { $event->object->setDelayRedirects(true); // save now, since ProcessPageView removes $_GET['it'] when it executes $it = isset($_GET['it']) ? $_GET['it'] : ''; if(!$this->isAssetPath($it)) { if(strpos($it, "processwire/") !== 0) $this->log->message("Original path: $it"); $it = $this->updatePath($it); if(strpos($it, "processwire/") !== 0) $this->log->message("Updated path: $it"); $_GET['it'] = $it; } } /** * Is the given path a site assets path? (i.e. /site/) * * Determines whether this is a path we should attempt to perform any language processing on. * * @param string $path * @return bool * */ protected function isAssetPath($path) { $config = $this->wire('config'); // determine if this is a asset request, for compatibility with pagefileSecure $segments = explode('/', trim($config->urls->assets, '/')); // start with [subdir]/site/assets array_pop($segments); // pop off /assets, reduce to [subdir]/site $sitePath = '/' . implode('/', $segments) . '/'; // combine to [/subdir]/site/ $sitePath = str_replace($config->urls->root, '', $sitePath); // remove possible subdir, reduce to: site/ // if it is a request to assets, then don't attempt to modify it return strpos($path, $sitePath) === 0; } /** * Given a page path, return an updated version that lacks the language segment * * It extracts the language segment and uses that to later set the language * */ public function updatePath($path) { if($path === '/' || !strlen($path)) { $this->user->language = $this->wire('languages')->getDefault(); return $path; } $trailingSlash = substr($path, -1) == '/'; $testPath = trim($path, '/') . '/'; $home = $this->wire('pages')->get(1); $found = false; foreach($this->wire('languages') as $language) { if($language->isDefault()) continue; $name = $language->name . "/"; if(strpos($testPath, $name) === 0) { $found = true; $this->user->language = $language; $path = substr($testPath, strlen($name)); break; } } if(!$found) $this->user->language = $this->wire('languages')->getDefault(); if(!$trailingSlash && $path != '/') $path = rtrim($path, '/'); return $path; } public function hookPageLocalUrl(HookEvent $event) { $lang = $this->getLanguage($event->arguments(0)); $event->return = $this->wire('config')->urls->root . ltrim(($lang->isDefault() ? "" : $lang->name) . $event->object->path, "/"); } public function hookPageLocalHttpUrl(HookEvent $event) { $this->hookPageLocalUrl($event); $url = $event->return; $event->return = $this->wire('input')->scheme() . "://" . $this->wire('config')->httpHost . $url; } /** * Given an object, integer or string, return the Language object instance * * @param int|string|Language * @return Language * */ protected function getLanguage($language) { if(is_object($language)) { if($language instanceof Language) return $language; $language = ''; } if($language && (is_string($language) || is_int($language))) { if(ctype_digit("$language")) $language = (int) $language; else $language = $this->wire('sanitizer')->pageNameUTF8($language); $language = $this->wire("languages")->get($language); } if(!$language || !$language->id || !$language instanceof Language) { $language = $this->wire('languages')->get('default'); } return $language; } public function ___install() { if($this->modules->isInstalled("LanguageSupportPageNames")) { throw new WireException($this->_("LanguageSupportPath and LanguageSupportPageNames cannot be active at the same time")); } } } This way, of course, the page paths after the prefix are identical for all languages, which might not be desired for SEO reasons. The module also may have side effects from setting the language that I didn't consider, so use at your own risk
    1 point
  35. You can also put this on your homepage template: <?php $page = $pages->get(123); // replace by the page you want to replace the homepage with include("./{$page->template}.php");
    1 point
×
×
  • Create New...