Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 09/17/2020 in all areas

  1. A new module that hasn't had a lot of testing yet. Please do your own testing before deploying on any production website. Custom Paths Allows any page to have a custom path/URL. Note: Custom Paths is incompatible with the core LanguageSupportPageNames module. I have no experience working with LanguageSupportPageNames or multi-language sites in general so I'm not in a position to work out if a fix is possible. If anyone with multi-language experience can contribute a fix it would be much appreciated! Screenshot Usage The module creates a field named custom_path on install. Add the custom_path field to the template of any page you want to set a custom path for. Whatever path is entered into this field determines the path and URL of the page ($page->path and $page->url). Page numbers and URL segments are supported if these are enabled for the template, and previous custom paths are managed by PagePathHistory if that module is installed. The custom_path field appears on the Settings tab in Page Edit by default but there is an option in the module configuration to disable this if you want to position the field among the other template fields. If the custom_path field is populated for a page it should be a path that is relative to the site root and that starts with a forward slash. The module prevents the same custom path being set for more than one page. The custom_path value takes precedence over any ProcessWire path. You can even override the Home page by setting a custom path of "/" for a page. It is highly recommended to set access controls on the custom_path field so that only privileged roles can edit it: superuser-only is recommended. It is up to the user to set and maintain suitable custom paths for any pages where the module is in use. Make sure your custom paths are compatible with ProcessWire's $config and .htaccess settings, and if you are basing the custom path on the names of parent pages you will probably want to have a strategy for updating custom paths if parent pages are renamed or moved. Example hooks to Pages::saveReady You might want to use a Pages::saveReady hook to automatically set the custom path for some pages. Below are a couple of examples. 1. In this example the start of the custom path is fixed but the end of the path will update dynamically according to the name of the page: $pages->addHookAfter('saveReady', function(HookEvent $event) { $page = $event->arguments(0); if($page->template == 'my_template') { $page->custom_path = "/some-custom/path-segments/$page->name/"; } }); 2. The Custom Paths module adds a new Page::realPath method/property that can be used to get the "real" ProcessWire path to a page that might have a custom path set. In this example the custom path for news items is derived from the real ProcessWire path but a parent named "news-items" is removed: $pages->addHookAfter('saveReady', function(HookEvent $event) { $page = $event->arguments(0); if($page->template == 'news_item') { $page->custom_path = str_replace('/news-items/', '/', $page->realPath); } }); Caveats The custom paths will be used automatically for links created in CKEditor fields, but if you have the "link abstraction" option enabled for CKEditor fields (Details > Markup/HTML (Content Type) > HTML Options) then you will see notices from MarkupQA warning you that it is unable to resolve the links. Installation Install the Custom Paths module. Uninstallation The custom_path field is not automatically deleted when the module is uninstalled. You can delete it manually if the field is no longer needed. https://github.com/Toutouwai/CustomPaths https://modules.processwire.com/modules/custom-paths/
    1 point
  2. I have a bilingual site. I want home to also include /en/ at the end, thus to be www.example.com/en/ (english being the default language). Is that doable?
    1 point
  3. I have opened a ticket on GitHub, in which I present a modification respectively a proof of concept, which significantly improves the editing of pages, especially with long contents. The save buttons are always in view with this modification, and the scroll position when editing and saving is saved and restored after saving. You can also find a screencast and code extensions on GitHub. What do you think of that? Link: https://github.com/processwire/processwire-requests/issues/177
    1 point
  4. Sorry @eydun, I only saw your question now. I already brought the Floating Buttons into the game in 2018 as a proof of concept. You can find the code for them here: Or directly on GitHub: https://github.com/processwire/processwire-requests/issues/177
    1 point
  5. Maybe this does not work (I'm on mobile), but have you tried to set a var in _init.php like this: if(isset($alreadyExecuted) && $alreadyExecuted) return; $alreadyExecuted = true; // set it in the first run. EDIT: Or bind the include of _functions.php on the condition of the var.
    1 point
  6. Version Update 2.0.0 The current version has got some improvements, bug fixes and new features. Many thanks to @Autofahrn, who created the idea and code base for copying multiple items at once! Amazing feature! Also, there is now the option to disable the copy and paste dialogs. Last but not least, thanks to @joshua, for suggesting a bug-fix in context with normal repeater fields. All information and downloads are updated in the first post.
    1 point
  7. Thanks! I can work around it for now. Issue opened: https://github.com/processwire/processwire-issues/issues/1247
    1 point
  8. It's a bug - please open an issue on GitHub to bring it to Ryan's attention. The URL segments array has a 1-based index but this is lost to a 0-based index when the array is reversed here: https://github.com/processwire/processwire/blob/ee4c46a442f09cf81f9e1800c5fdfcd1176f538a/wire/core/WireInput.php#L576 As a workaround for now you could do this: $segments = $input->urlSegments; $last_segment = end($segments);
    1 point
  9. I've added a note about the incompatibility with LanguageSupportPageNames to the module readme. I'm not sure how LanguageSupportPageNames works exactly or what part it plays in multi-language functionality but I can see that, like Custom Paths, it hooks Page::path and performs redirects before pages are viewed. This makes me think it may be impossible for these two modules to work together, but if anyone with multi-language experience can see a solution I'd be glad to apply any fix.
    1 point
  10. @Robin S was very kind and had a deeper look at my problem and found the problem:
    1 point
  11. v0.1.4 released: this version adds the functionality that if a visitor attempts to view a page at its real path (maybe they have it bookmarked or are following an old link) they are redirected to the custom path.
    1 point
  12. I can't reproduce that. If I set the custom path to something that it is in PagePathHistory for the page then I can successfully view the page at the custom path without being redirected by PagePathHistory. If you can give me some steps to follow that will consistently reproduce the problem on a clean installation let me know and I'll try and investigate further.
    1 point
  13. I'm sure it's the less used path, but a CLI is useful for anybody automating deployments either using some kind of CI/CD or manually called scripts. The goal of my migrations module was to result in reproducable db state, so automation is possible. If migrations can be run arbitrary times it's not going to do that – e.g. a field created and later deleted is not the same as a field deleted and later created. Therefore migrations have a fixed order (by timestamp) and a db table keeps knowledge about which migrations were already applied before.
    1 point
  14. The cloning is in the scrolling event, because PW also clones the buttons at the page load (for the head area). If I clone the original savebuttons during pageload, they will also be duplicated in the head. However, it is ensured that this event is only executed once during scrolling as soon as the top threshold is reached. If a page is not long enough, no button needs to be cloned. The position storage is also intercepted with a debounce. The position is not saved until 250 milliseconds after the end of the scrolling event. It may look like this in the code, but any manipulation of the DOM is done only once.
    1 point
  15. 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
  16. I have coded my sites using simple included header & footer technique (similar to how demo site is coded). It has it's merits (simple and straightforward), but on bigger sites it may add lot's of controller logic to header files or a lot of little bit different template files, where logic and markup is mixed. I know there is TemplateFile class which I assume is something that Ryan uses on most of his projects. Usage looks simple: <?php $out = new TemplateFile("./includes/my_markup.html"); $out->set('headline', $page->get("headline|title")); $out->set('body', $page->body); $out->set('sidebar', $page->sidebar); $out->set('navigation', $pages->find("parent=/")); echo $out->render(); But how I would code those headline, body etc. variables to my_markup.html file? I assume that my_markup.html can contain php... So are those just $headline, $body, $sidebar etc? Or probably like $this->headline etc?
    1 point
  17. As for how to use the TemplateFile class, you've got it exactly right. You can access everything you set() directly from the var name in the file, such as $headline and $body, etc. If you prefer it, you can also use the setArray() method (inherited from WireData) to do something like this (though I think I prefer the readability of your version): <?php echo $out->setArray(array( 'headline' => $page->get("headline|title"), 'body' => $page->body, 'sidebar' => $page->sidebar, 'navigation' => $pages->find("parent=/") ))->render(); TemplateFile is the class that PW uses to output your templates. I actually don't use it very often in my own sites. That's in part because I work mostly alone and don't have to compartmentalize stuff quite as much as if the work was split. I do think it makes sense to use TemplateFile more and more as the size of the team grows and you need templates with limited access and scope (as a good thing). The strategy that I use does not have limited access and scope, but it is probably more efficient and less verbose than using the TemplateFile class. Though it's also a similar approach in many ways too. The way it works is that all the site templates pull in the same main markup file (main.php). That main markup file is looking for values to be set to the $page object… whether those values were set in PW, or by some other template. Templates may also modify the values (usually appending or prepending) before sending to the main template. If an expected value is not set, then the main template supplies a default. So templates really only need to supply values for those things that they want to change. This is what that main.php markup file might look like: /site/templates/main.php <?php // set default values for topnav and subnav. // these aren't PW fields, so we're just using $page to hold values that other templates can override if(!$page->topnav) $page->topnav = $pages->get("/")->children(); if(!$page->subnav) $page->subnav = $page->children(); // we want all templates to have jquery, main.js and main.css $config->scripts->add('jquery.js'); $config->scripts->add('main.js'); $config->styles->add('main.css'); // if a JS or CSS file has the same name as the template, then use it if(is_file($config->paths->templates . "scripts/$template.js")) $config->scripts->add("$template.js"); if(is_file($config->paths->templates . "styles/$template.css")) $config->styles->add("$template.css"); // now output the markup ?> <!DOCTYPE html> <html lang="en"> <head> <title><?php echo $page->get("browser_title|headline|title"); ?></title> <?php foreach($config->scripts as $file) { echo "<script src='{$config->urls->templates}scripts/$file'></script>"; } foreach($config->styles as $file) { echo "<link rel='stylesheet' type='text/css' href='{$config->urls->templates}styles/$file' />"; } ?> </head> <body id='body_<?php echo $page->rootParent->name; /* for targeting in CSS */ ?>'> <div id='topnav'> <?php echo $page->topnav->render(); ?> </div> <div id='subnav'> <?php echo $page->subnav->render(); ?> </div> <div id='bodycopy'> <h1><?php echo $page->get('headline|title'); ?></h1> <?=$page->body?> </div> <div id='sidebar'> <?=$page->sidebar?> </div> </body> </html> Then all the other templates in the site customize the variables that get populated, and they pull in the main template. For instance, the homepage template: /site/templates/home.php <?php // we don't want subnav on homepage, so make it empty $page->subnav = new PageArray(); // list the 3 newest news items in the sidebar $page->sidebar = "<h2>Latest News</h2>" . $pages->find("parent=/news/, sort=-date, limit=3")->render(); // since it's the homepage, we'll add a masthead photo above the body if($page->photo) { $photo = $page->photo->size(600, 200); $page->body = "<img id='masthead_photo' src='{$photo->url}' alt='{$photo->description}' />" . $page->body; } // add a note about when it was last updated, just for kicks $page->body .= "<p>Last updated " . date('m/d/Y H:i:s', $page->modified) . " by {$page->modifiedUser}</p>"; // include the main template include("./main.php"); I also want to mention that main.php isn't actually used directly by any pages... I don't even keep it as a template in PW. Though you certainly could. But I just use main.php for inclusion by other templates. That's the approach I use most often anyway. What other approaches to people use?
    1 point
×
×
  • Create New...