-
Posts
5,009 -
Joined
-
Days Won
333
Everything posted by Robin S
-
You could write a simple textformatter module to replace instances of "my-simple-class" with "my-long list-of class-names".
-
That is insane. Maybe time to move to a new host.
-
URL Segment showing 404 when i tried to open page in browser
Robin S replied to Junaid Farooqui's topic in Dev Talk
Good to know - I had read on Stack Overflow that it was an efficient way to return the string of characters occurring before a substring but never tested it. Lets try that again... At the top of template files where child pages need the custom ".html" URLs: if(empty($options['pageStack']) && $input->urlSegment1) { $name = $sanitizer->pageName(rtrim($input->urlSegment1, '.html')); $p = $pages->findOne("parent=$page, name=$name"); if($p->id) { echo $p->render(); $this->halt(); } else { throw new Wire404Exception(); } } In /site/ready.php: $this->addHookAfter('Page::path', function($event) { $page = $event->object; $tpls = ['basic_page', 'some_template']; // define template names if(in_array($page->template, $tpls)) { $return = rtrim($event->return, '/'); // remove trailing slash if present $event->return = $return . '.html'; } }); Not that I think any of this is a good idea. Better to tell the SEO team that there is no reason to prefer /my-page.html over /my-page/.- 6 replies
-
- 2
-
-
- seo
- urlsegment
-
(and 1 more)
Tagged with:
-
URL Segment showing 404 when i tried to open page in browser
Robin S replied to Junaid Farooqui's topic in Dev Talk
For the URL /products/product-one.html, as kongondo says ".html" will not be recognised a valid URL segment in the template for "product-one". But "product-one.html" would be a valid URL segment in the template for "product". So you would need to enable URL segments for every template and at the start of every template file you could have something like this: if($input->urlSegment1) { $name = strtok($input->urlSegment1, '.html'); $p = $page->children->get("name=$name"); if($p->id) { echo $p->render(); $this->halt(); } else { throw new Wire404Exception(); } }- 6 replies
-
- 1
-
-
- seo
- urlsegment
-
(and 1 more)
Tagged with:
-
Assuming you are rendering your child pages in container elements with an ID matching the page name: $nav = $modules->get('MarkupSimpleNavigation'); $nav->addHookAfter('getItemString', function(HookEvent $event) { $item = $event->arguments('page'); // if the item has more than one parent then it is a subpage if($item->parents->count() > 1) { $event->return = "<a href='{$item->parent->url}#{$item->name}'>$item->title</a>"; } }); // define your options array if needed and render your menu You may want to block direct access to the subpages, in which case see this thread:
-
Disallow accessing page using template via it's url
Robin S replied to LimeWub's topic in General Support
A couple more options... At the top of the file for the template of pages you are including inside another page: if(empty($options['pageStack'])) throw new Wire404Exception(); if($page->url == $_SERVER['REQUEST_URI']) throw new Wire404Exception(); A related thread: -
-
As a general rule, you can copy any PW module from /wire/modules/ to /site/modules/ if you want to customise it. When you do a Modules > Refresh you will see a notice... Session: Module "SomeModule" has multiple files (bold file is the one in use). Click here to change which file is used ...and you can enter the module settings to switch between the version in /wire/ and the version in /site/.
-
You can certainly create your own plugin and toolbar button for CKEditor. PW doesn't get in the way of that, but it's something that you would learn about in the CKEditor docs rather than the PW docs. You can place your plugin in /site/modules/InputfieldCKEditor/plugins/ and then select it for CKEditor fields in the field settings on the Input tab. Or if you want to include your CKEditor plugin in a PW module you could have a look at how HannaCodeHelper does it. You will need to include the name of the toolbar button in the CKEditor Toolbar section of the field settings. Copy /wire/modules/Inputfield/InputfieldCKEditor/plugins/pwlink/ to /site/modules/InputfieldCKEditor/plugins/pwlink/ and make your changes there.
-
He talks about the separation of concerns... ...and MVC is a popular pattern that enforces that. But they're not exactly the same thing, for sure.
-
I think this new approach is similar to template engines in one respect: the idea of extending a named block. This feature is present in template languages like Smarty and Twig and I for one find that feature very useful. I don't see any other similarities to template engines though. What would be your idea of misuse of this new strategy? If you mean it allows (encourages?) developers to not follow the MVC pattern then I don't see this as a big issue. There is no cardinal rule: "Thou shalt use MVC in all projects" - it depends very much on the type of developer you are and the type of project you are working on. When Ryan says... ...I take this to mean people who are new to PHP development in general. People who have a design background, or those used to a drag-and-drop interface, or who have previously worked only with static HTML. If someone has a lot of PHP experience I doubt they would find anything about PW difficult to understand - more like a breath of fresh air. And people who are new to PHP development are not going to be: building large, complex web projects working on long-lived projects that will be handed over to future developers collaborating on a project with other developers in a team For any of these I totally see the value of MVC. But if you are a newbie working on <10 page brochure websites you do not need MVC.
-
add page selector to module configuration
Robin S replied to Marc's topic in Module/Plugin Development
The error is visible if you install Tracy Debugger. -
Not sure how you got the rectangular thumbnails - mine are always square when rendered inside a PageTable, regardless of the the image field settings. Which isn't a bad thing in this case because the solution involves overriding the JS image sizing with CSS and you're not going to be able to preserve the aspect ratio for each image. These custom CSS settings (use AdminCustomFiles or AdminOnSteroids) gave the result that follows. .Inputfield_pt_thumbnails .InputfieldImage .gridImage__overflow img { height:100%; } .Inputfield_pt_thumbnails td:nth-child(2) .InputfieldImage .gridImage__overflow { height:260px !important; width:260px !important; } .Inputfield_pt_thumbnails td:nth-child(3) .InputfieldImage .gridImage__overflow { height:100px !important; width:100px !important; } There is no way to identify individual image fields from the markup so you have use nth-child() selectors to target table columns. Portrait-format images will not fill their frames.
-
add page selector to module configuration
Robin S replied to Marc's topic in Module/Plugin Development
The inputfield value is not saved correctly because config you are trying creates an error: PHP Notice: Object of class ProcessWire\Page could not be converted to int in ...\modules\Process\ProcessModule\ProcessModule.module:1287 So it seems that the inputfield you have created is returning a page object when what is expected is a page id. One solution is to create the options you want to make available in the inputfield: class ProcessHelloConfig extends ModuleConfig { public function __construct() { $items = $this->pages->find("parent=1"); $page_options = []; foreach($items as $item) { $page_options[$item->id] = $item->title; } $this->add(array( // Text field: greeting array( 'name' => 'greeting', // name of field 'type' => 'text', // type of field (any Inputfield module name) 'label' => $this->_('Hello Greeting'), // field label 'description' => $this->_('What would you like to say to people using this module?'), 'required' => true, 'value' => $this->_('A very happy hello world to you.'), // default value ), // Radio buttons: greetingType array( 'name' => 'greetingType', 'type' => 'radios', 'label' => $this->_('Greeting Type'), 'options' => array( // options array of value => label 'message' => $this->_('Message'), 'warning' => $this->_('Warning'), 'error' => $this->_('Error'), ), 'value' => 'warning', // default value 'optionColumns' => 1, // make options display on one line 'notes' => $this->_('Choose wisely'), // like description but appears under field ), // My custom test field array( 'name' => 'myTest', 'type' => 'select', 'label' => $this->_('Test'), 'options' => $page_options, ), )); } } BTW, if you want to allow the user to select any page from the tree you can use the Page List Select inputfield: // My custom test field array( 'name' => 'myTest', 'type' => 'PageListSelect', 'label' => $this->_('Test') ) -
I think a separate mobile website is an outdated approach and device sniffing will be both unreliable and require more maintenance. I would highly recommend a single responsive design, but if you're sure you want to pursue separate templates for mobile devices then you could select templates by domain as suggested here... ...or use the same approach but test for device using Mobile Detect.
-
Files by language, how would you do it?
Robin S replied to heldercervantes's topic in General Support
The actual repeater item. I also installed Language Support and set up a test Page field with template=language and that works too. $results = $page->test_repeater->find("test_page.name=german"); echo $results->each("<p>{name}</p>"); // echoes the repeater item name, e.g. 1484443861-212-1 Edit: fixed the above -
Files by language, how would you do it?
Robin S replied to heldercervantes's topic in General Support
Maybe this issue is specific to language pages when used in a Page field, because I can successfully find repeater items with a Page field matching a given id, name, title, etc. -
The "Add New" link is automatically hidden when the max is reached. To hide the repeater item label for repeaters with min and max of 1 you can use a CSS rule like this in AdminCustomFiles or AdminOnSteroids: .InputfieldRepeater[data-min="1"][data-max="1"] .InputfieldRepeaterHeaderInit { display:none; } If you do this you would want to have your repeater set to "Items always open".
-
This is just an idea... You could consider making the creation and maintenance of these articles easier for site editors by having a simpler structure in the page tree (just the categories as parent pages), entering the article date with a datetime field, and then creating the desired URL for the frontend using URL segments (enable this on the category template). So your category template would look for the following URL segments: segment 1: year - sanitize to integer, throw 404 if out of range segment 2: month - sanitize to integer, throw 404 if out of range segment 3: day - sanitize to integer, throw 404 if out of range segment 4: article page name - throw 404 if no match for article page name In terms of finding articles that match a given year, month or day you could convert to a timestamp range as Ryan shows here, but to make it easier (and considering you'll need the integers for building the article URLs) I would instead add 3 integer fields to your article template, set the field visibility to "Hidden (not shown in editor)" and then populate them with a saveReady hook. // in /site/ready.php $this->pages->addHookAfter('saveReady', function($event) { $page = $event->arguments('page'); if($page->template->name === 'article' && $page->article_date) { $page->day = date('d', $page->article_date); $page->month = date('m', $page->article_date); $page->year = date('Y', $page->article_date); } }); Now it's really easy to find articles, e.g. $matches = $pages->find("template=article, year=2016, month=11, sort=sort"); For the question in your original post you'd do something like this: $latest_article = $pages->get("template=article, parent=/politics/, sort=-article_date"); $recent_articles = $pages->find("template=article, parent=/politics/, article_date={$latest_article->article_date}, sort=sort, limit=5"); $day_link = "/politics/{$latest_article->year}/{$latest_article->month}/{$latest_article->day}"; // use this as the first link to the 'parent' page When you need to output the URL of an article you would build it like this: $url = "{$article->parent->url}{$article->year}/{$article->month}/{$article->day}/{$article->name}/"; For convenience you'd probably make a simple function that returns this URL string. In the backend, rather than browse through the page tree, if you want to list articles by day/month/year you can use the "Find" lister. Or better yet a dedicated Lister Pro instance for articles.
-
@Tom., I think BitPoet's module is the way to go, but in case you can't use it (e.g. your MySQL doesn't have timezone support enabled) you could use a saveReady hook to populate a hidden field with the day of the week of the entered date. // in /site/ready.php $this->pages->addHookAfter('saveReady', function($event) { $page = $event->arguments('page'); if($page->template->name === 'act' && $page->date_field) { $page->day_of_week = date('l', $page->date_field); } }); // find pages $pages->find("template=act, day_of_week=Friday");
-
A Snipcart integration case study, as mentioned in the Showcase forum... Les Ateliers Fromagers: Custom Shopping Cart Integration on a ProcessWire CMS Site https://snipcart.com/blog/case-study-ateliers-fromagers-processwire Also on the Snipcart site: https://snipcart.com/blog/processwire-ecommerce-tutorial
-
This is freaking awesome - I love it! I've always disliked working with HTML markup inside PHP variables - the sacrificed readability of the HTML that comes with multiple variable concatenations, the single quotes/double quotes/escaped quotes hassle. I try to avoid it as much as possible using output buffering but this new feature suits me down to the ground and will definitely be my preferred way of managing markup in templates going forward. Simple and brilliant, like the rest of PW. Thanks!
-
Do you mean that the PW htaccess is disallowing access to your PHP file (you are getting the 404 page)? PW blocks direct access to PHP files inside /site/ but you should be able to access it inside the root, e.g. /api.php ...or... /xapi/index.php
-
I'm not sure about generating a new userAuthSalt, but in the future if you want to reuse an existing site as the starting point of a new site then check out the Site Profile Exporter module.
-
That seems less flexible that the PW approach to image sizing. What is the advantage of it? If it's that you can type 'link-image' in your code rather than '630, 330' then you could achieve the same in PW: // in an init.php that is auto-prepended to template files $link_image = '630, 330'; // use this in your template files $page->image->size($link_image)->url; Or using Croppable Image, you define a crop... ...then call it by name in your template... $page->image->getCrop('link-image')->url;