Leaderboard
Popular Content
Showing content with the highest reputation on 10/30/2017 in all areas
-
Wishlist --> Posted Saturday at 03:12 AM New Module --> Posted Saturday at 06:08 AM crazy4 points
-
You can adapt the following Hanna Code example to a function for output anywhere... without dependencies ---------------- Jumplinks Hanna Code This Hanna code is meant to be used in your body copy. It collects all the headline tags in the text and turns them into anchor jump links while outputting a linked table of contents. It will put the table of contents wherever you type the Hanna code. $for = str_replace(',', ' ', $for); $for = explode(' ', $for); foreach($for as $k => $v) $for[$k] = trim($v); $for = implode('|', $for); $anchors = array(); $value = $hanna->value; if(preg_match_all('{<(' . $for . ')[^>]*>(.+?)</\1>}i', $value, $matches)) { foreach($matches[1] as $key => $tag) { $text = $matches[2][$key]; $anchor = $sanitizer->pageName($text, true); $anchors[$anchor] = $text; $full = $matches[0][$key]; $value = str_replace($full, "<a name='$anchor' href='#'></a>$full", $value); } $hanna->value = $value; } if(isset($topic)) { $topic = $topic; } else { $topic = 'Page'; } if(count($anchors)) { echo "<div class='toc'>"; echo "<p>On this $topic:</p>"; echo "<ol class='article-toc'>"; foreach($anchors as $anchor => $text) { echo "<li><a href='$page->url#$anchor'>$text</a></li>"; } echo "</ol>"; echo "</div>"; } else { echo ''; } Usage Examples: [[jumplinks]] Locates all h2 and h3 headlines, turns them into anchors, and generates a table of contents. This is the default behavior with no attributes. [[jumplinks for=h2]] Here we specify a 'for' attribute. It produces the same behavior as above except only anchors h2 headlines. [[jumplinks for="h2 h4"]] Same as above except only anchors h2 and h4 headlines. ---------------- $for is the heading tags that you want to link in the TOC $hanna->value is the string with the html content you want to process and update This script modify the original HTML content to include the new anchors, and create the markup for the TOC. Instead of direct echo the markup, you need to return the output... maybe something like the following code (you need to check if I'm using the PHP best practices because I'm not a coder) function toc( $heading, $content ) { $heading = str_replace( ',', ' ', $heading ); $heading = explode( ' ', $heading ); foreach ( $heading as $k => $v )$heading[ $k ] = trim( $v ); $heading = implode( '|', $heading ); $anchors = array(); if ( preg_match_all( '{<(' . $heading . ')[^>]*>(.+?)</\1>}i', $content, $matches ) ) { foreach ( $matches[ 1 ] as $key => $tag ) { $text = $matches[ 2 ][ $key ]; $anchor = $sanitizer->pageName( $text, true ); $anchors[ $anchor ] = $text; $full = $matches[ 0 ][ $key ]; $content = str_replace( $full, "<a name='$anchor' href='#'></a>$full", $content ); } } if ( count( $anchors ) ) { $toc = "<ul class='article-toc'>"; foreach ( $anchors as $anchor => $text ) { $toc .= "<li><a href='$page->url#$anchor'>$text</a></li>"; } $toc .= "</ul>"; return array( $toc, $content ); } else { return null; } } ..or maybe output only the $anchors array and customize the markup in your template according to your page design4 points
-
In response to a wishlist request... Field Save + Add New Adds a "Save + Add New" button when editing a field. Usage Install the Field Save + Add New module. When editing a field, click "Save + Add New" if you want to save the current field and start the process of adding a new field. Note: The button will not redirect you to "Add New" if you are performing some special action such as duplicating a field or adding a field to a template. https://github.com/Toutouwai/FieldSaveAdd/3 points
-
3 points
-
Yes, ofcourse. But as @SamC said. Why not make the whole site in PW. It will cost a little time, but you'll have even more flexibility than with a static site.3 points
-
It should be possible to start with the original ProcessWire 2.3 + Skyscrapers v1 combo and you should be able to upgrade it step-by-step to 2.4, 2.5, 2.6 etc up to 3.0.x. Sure, you need to dig up all the relevant upgrade instructions and follow them carefully and manual changes might be needed here and there too, but in the end you will probably get what you need.2 points
-
The "http" may be optionally prepended to any property accessed from $config->urls (including those you add yourself). https://github.com/processwire/processwire/blob/57b297fd1d828961b20ef29782012f75957d6886/wire/core/Paths.php#L492 points
-
True.. Maybe better to get it like this...(in case down the road someone wonders what the 2 is all about, etc).. $pages($config->adminRootPageID)->httpUrl();2 points
-
Keep it simple. There are dozens of JS libraries out there that generate table of contents for you. Google "jquery toc"2 points
-
Why not use a repeater field with title and body instead of one single CKEditor field? You could then just iterate over the repeater items, render the anchors when outputting the titles and then iterate again in your TOC to render the links.2 points
-
2 points
-
Thank you @ryan for pointing me in the right direction. Problem solved. FormBuilder was a red herring, all good there. The cryptic debug message was key to finding the cause. I refer to the home page throughout the site and normally add $homePage = $pages->get('/'); in the _init.php file. Tried to be too clever and tweak page load speed by reducing the number of database calls so put the following below the LoginRegister code: // shortcut to home page saved in session $homePage = $session->get('home-page'); // Fairly certain this is the culprit! if (!$homePage) { $homePage = $pages->get('/'); $session->set('home-page', $homePage); } While the above works for $cache, it doesn't for $session, or even replacing $session with $_SESSION and using array_key_exists('home-page', $_SESSION), etc. Reverted to $homePage = $pages->get('/'); for every page and Login/Register working perfectly.2 points
-
Another option for adding elements at the end of <head>: $wire->addHookAfter('AdminTheme::getExtraMarkup', function(HookEvent $event) { $parts = $event->return; $parts['head'] .= "<script src='/path/to/script.js'></script>"; $event->return = $parts; });2 points
-
I am getting a little OT, but it's possible to support commas and complex data types in CSV with a proper CSV parser. PHP's native ones are not great. I make use of https://github.com/parsecsv/parsecsv-for-php in a couple of my modules. It's an older library that doesn't appear to be maintained anymore. I think there might be better ones out there, but at the time it handled everything I needed better than anything else I found. Back to the topic at hand - I am curious about a feed of 1300 pages - that could definitely take a little while to process. It's a shame it's not just addition of new pages - you could make that very quick if the xml feed entries had a date. But if you have to process them all for updates and deletions, you will be relying on the title of the page for matches. Will you just update them all, or will you compare the contents of fields for differences and process only if there has been a change?2 points
-
2 points
-
@Ahmad This module has a problem in the AllInOneMinify.module file ... When you go to the processwire installation directory and site\modules\AllInOneMinify/AllInOneMinify.module And change this code from the line 713: foreach ($files as $file) { $_timestamp = ($_timestamp + $file['last_modified']); } Change to : foreach ($files as $file) { $_timestamp = ($file['last_modified']); } I only deleted the variable " $_timestamp + " and it worked ... But I do not know if it will have any later consequences ... In addition, you should install a great debugging module that will help you find problems with the name Tracy Debugger1 point
-
Hello @Ahmad ... You must add a backslash before \AIOM like: <script src="<?php echo \AIOM::JS(array('assets/js/uikit.min.js', 'assets/js/uikit-icons.min.js')); ?>"></script> In this case, the js files are in the assets / js directory ...1 point
-
Enable debug mode in site/config.php. You're probably getting an error that's preventing PW to complete page render.1 point
-
Thanks guys, I guess for now I'll just add an "Images" field to the template and have that be the container for inserted images. I'll admit I'm finding this a bit convoluted but we'll make it work for our users. @BitPoet - I'll check out your Media library module in addition.1 point
-
you achieve that using the simple html dom parser, just have it scan for the anchors; the Process Documentation module has an example that will do exactly what you need; you can download a copy of the simple html dom parser and put it somewhere you can include it, and then process the body field as is shown in the example... https://github.com/outflux3/ProcessDocumentation/blob/master/examples/uikit-example.php1 point
-
I found out the solution, there was another module to install, Inputfield Selectize Multiple . thanks again for this module.1 point
-
Hi @flydev ! Great plugin, works mostly like a charm! I had 2 issues tough: 1. with google, matching first- and last-name and usernames does not work with our setup (special chars in names that are not reflected in the username etc). I think, this makes the plugin somewhat unflexible. Would be great to have the option configure the matching, or at least an option to only match the users mail (checkbox in the backend). I just saw the "options" "scope" settings in your github json and wonder if this is already implemented but not documented? 2. We run our new page in a subdirectory and the redirect url is wrong (this is more of a process-wire issue since its not easy to get the absolute urls from the api) this results in path being present twice in the redirect url: Problem: urls()->root + urls()->admin = //domain.com/path/ + /path/admin/ > //domain.com/path/path/admin/ This solution would be the following: // inside init() $this->backendUrl = pages()->get('path="'.str_replace(urls()->root, '', urls()->admin).'", include=all')->httpUrl; Keep up the great work!1 point
-
@Sérgio Jardim and I are gonna be there and decided a beer is in order. If you're going to be there, let's hang out.1 point
-
Template caching maybe? Check the Cache tab when editing the relevant template. As for CSS, browser cache? Chrome is notoriously 'cachy!'. You will want to develop with dev inspector open and set not to cache, if that is the case.1 point
-
You need to have at least one image field on the template, then you'll see an "Upload Image" button on the insert image dialog.1 point
-
You have two stand alone queries with no relation between them. Tag_code is not relating them in this case. You should do something like this... $cities = $pages->find("template=t3Cities_list, sort=title"); foreach ($cities as $c){ echo <div class="row">' . $c->title . '</row'; foreach($c->tag_code as $t){ echo $t->title . ' | '; } } I usually make it a function in _func.php1 point
-
I'll try that, thanks. Looking at that chunk of code, it's not about setting items to an uninitialised array with $paths[] = $path (which is okay) but if $iter is empty then $paths does not exist.1 point
-
1 point
-
1 point
-
never used it but you could save another line with conditional hooks https://processwire.com/blog/posts/new-ajax-driven-inputs-conditional-hooks-template-family-settings-and-more/#new-conditional-hooks $wire->addHookAfter('Page(template=admin)::render', function($event) { ... });1 point
-
@bernhard Here is the code I used on site/ready.php and it works great: if($this->page->template == 'admin') { $this->addHookAfter('Page::render', function($event) { $css = wire('config')->urls->templates . 'styles/AdminThemeUikit.css?v=1'; $js = wire('config')->urls->templates . 'scripts/AdminThemeUikit.js?v=1'; $event->return = str_replace("</head>", "\n<link type='text/css' href='{$css}' rel='stylesheet'/>\n</head>", $event->return); $event->return = str_replace("</body>", "\n<script type='text/javascript' src='{$js}'></script>\n</body>", $event->return); }); }; I've also uninstalled Admin Custom Files since I was only using it to inject theme files. Thank you.1 point
-
You can also inject scripts and styles by hooking the page render and doing a str_replace("</head>", $yourscripts . "</head>", $event->return)1 point
-
@PWaddict Thanks for your report, I've added an extra hook (after AdminTheme::getExtraMarkup) and updated the version number. Changes are uploaded to GitHub. https://github.com/Da-Fecto/AdminCustomFiles1 point
-
The main point here is that each ProcessWire site is unique. There's no 100% sure answer we can tell you without digging deeper into your codebase. That being said, you could try changing the lines you've posted here to something like this: $static_translations['telephone']['default'] = "Τηλ:<br><a href='tel:2821011111'>2821011111</a>"; $static_translations['telephone']['english'] = "Phone:<br><a href='tel:+302821011111'>00302821011111</a>"; Please be aware that this might not work as expected, and it might look awful if your site's stylesheet don't expect these numbers to be links. You should also test both versions afterwards to make sure that they actually work as expected – i.e. result in a call.1 point
-
1 point
-
Let's do a comparison of how you would do this with the typical delayed output approach vs Markup Regions. When it comes to the Markup Regions example I'll do it a little differently than you've proposed it, with a dedicated <region> for scripts instead of appending to <head>. Delayed output _init.php $scripts = ''; _main.php <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <?= scripts ?> </head> //... template-which-needs-js.php if(strpos($page->name, 'special') === 0) { $scripts .= "<script src='{$config->urls->templates}assets/js/my-script_2.js'</script>"; } else { $scripts .= "<script src='{$config->urls->templates}assets/js/my-script_1.js'</script>"; } Markup Regions _init.php Nothing needed here because one of the nice things about Markup Regions is that you don't need to initialise a markup variable. _main.php <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <region id="scripts"></region> </head> //... template-which-needs-js.php <region id="scripts" pw-append> <?php if(strpos($page->name, 'special') === 0): ?> <script src="<?= $config->urls->templates ?>assets/js/my-script_2.js"></script> <?php else: ?> <script src="<?= $config->urls->templates ?>assets/js/my-script_1.js"></script> <?php endif; ?> </region> So comparing a markup region to a variable: Use pw-append where you would have used $some_var .= 'something' Use pw-prepend where you would have used $some_var = 'something' . $some_var Use neither pw-append nor pw-prepend where you would have used $some_var = 'something' But Markup Regions are even more powerful because you can have multiple nested markup regions in _main.php, which is something you cannot do with variables.1 point
-
Pretty sure that's just a typo, and should read "This does the same as above". You can do anything with Markup Regions that you can do with the typical delayed output approach. Each markup region serves the same purpose as some variable that you would put markup in and output in _main.php, like $sidebar or whatever. There are a few ways. Here is one... _main.php (just showing the main content part - of course there will be <head>, footer, etc in this file too) <region id="main-content"> <region id="top"> <div class="full-width-coloured-bg"> <div class="container-1400px"> <div>SOME STUFF IN A CONTAINER</div> </div> </div> </region> <div class="container-1400px"> <div class="row"> <div class="col-10"> LEFT SIDE </div> <div class="col-2"> SIDEBAR </div> </div> </div> </region> basic-page.php This file can be empty because _main.php is based on the markup needs of basic-page. But until this bug is fixed you might want to include some dummy region in basic-page.php or else the Markup Regions parser won't be triggered and <region> tags in _main.php will not be removed. home.php <region id="main-content"> <div class="container-1400px"> <div>SOME STUFF IN A CONTAINER</div> </div> </region> services-page.php <region id="top"> <div class="full-width-coloured-bg"> <div class="container-1400px"> FULL WIDTH STUFF </div> </div> <div class="container-1400px"> <div>SOME STUFF IN A CONTAINER</div> </div> </region>1 point
-
@SamC, I don't entirely follow what you are saying, but here are a few things that might help. 1. You can remove elements in _main.php by using "pw-remove" in a template file. _main.php <div id="main"> FULL WIDTH OR SIDEBAR IN HERE </div> <div id="sidebar"> THE SIDEBAR </div> basic-page.php <!-- Remove #sidebar --> <div id="sidebar" pw-remove></div> 2. You can have as many nested ID'd or region elements in _main.php as you like, and then modify/replace any of them from your template. _main.php <region id="main"> <div class="container"> <div id="main"> FULL WIDTH OR SIDEBAR IN HERE </div> <div id="sidebar"> THE SIDEBAR </div> </div> </region> home.php <div id="sidebar"> <p>Just customise the sidebar.</p> </div> basic-page.php <region id="main"> <div class="container"> <p>Use a completely different #main on this template.</p> </div> </region> 3. The three blog posts about Markup Regions can be a bit confusing because the spec changed as the feature was developed and none of the posts cover the entire set of available keywords and syntax. Check out the comments in WireMarkupRegions.php for a more comprehensive spec. /** * Identify and populate markup regions in given HTML * * To use this, you must set `$config->useMarkupRegions = true;` in your /site/config.php file. * In the future it may be enabled by default for any templates with text/html content-type. * * This takes anything output before the opening `<!DOCTYPE` and connects it to the right places * within the `<html>` that comes after it. For instance, if there's a `<div id='content'>` in the * document, then a #content element output prior to the doctype will replace it during page render. * This enables one to use delayed output as if it’s direct output. It also makes every HTML element * in the output with an “id” attribute a region that can be populated from any template file. It’s * a good pairing with a `$config->appendTemplateFile` that contains the main markup and region * definitions, though can be used with or without it. * * Beyond replacement of elements, append, prepend, insert before, insert after, and remove are also * supported via “pw-” prefix attributes that you can add. The attributes do not appear in the final output * markup. When performing replacements or modifications to elements, PW will merge the attributes * so that attributes present in the final output are present, plus any that were added by the markup * regions. See the examples for more details. * * Examples * ======== * Below are some examples. Note that “main” is used as an example “id” attribute of an element that * appears in the main document markup, and the examples below focus on manipulating it. The examples * assume there is a `<div id=main>` in the _main.php file (appendTemplateFile), and the lines in the * examples would be output from a template file, which manipulates what would ultimately be output * when the page is rendered. * * In the examples, a “pw-id” or “data-pw-id” attribute may be used instead of an “id” attribute, when * or if preferred. In addition, any “pw-” attribute may be specified as a “data-pw-” attribute if you * prefer it. * ~~~~~~ * Replacing and removing elements * * <div id='main'>This replaces the #main div and merges any attributes</div> * <div pw-replace='main'>This does the same as above</div> * <div id='main' pw-replace>This does the same as above</div> * <div pw-remove='main'>This removes the #main div</div> * <div id='main' pw-remove>This removes the #main div (same as above)</div> * * Prepending and appending elements * * <div id='main' class='pw-prepend'><p>This prepends #main with this p tag</p></div> * <p pw-prepend='main'>This does the same as above</p> * <div id='main' pw-append><p>This appends #main with this p tag</p></div> * <p pw-append='main'>Removes the #main div</p> * * Modifying attributes on an existing element * * <div id='main' class='bar' pw-prepend><p>This prepends #main and adds "bar" class to main</p></div> * <div id='main' class='foo' pw-append><p>This appends #main and adds a "foo" class to #main</p></div> * <div id='main' title='hello' pw-append>Appends #main with this text + adds title attribute to #main</div> * <div id='main' class='-baz' pw-append>Appends #main with this text + removes class “baz” from #main</div> * * Inserting new elements * * <h2 pw-before='main'>This adds an h2 headline with this text before #main</h2> * <footer pw-after='main'><p>This adds a footer element with this text after #main</p></footer> * <div pw-append='main' class='foo'>This appends a div.foo to #main with this text</div> * <div pw-prepend='main' class='bar'>This prepends a div.bar to #main with this text</div> * * ~~~~~~1 point
-
To the best of my knowledge, there is no module that will make phone numbers on your site clickable. We have a Phone Fieldtype, but I don't think that's what you want.1 point
-
Hello, I have the same problem today and done this to solve that: $your_field->label = ''; //first need to set field label as empty string (important!) $your_field->skipLabel = true; //works only if the label is set to empty string regards.1 point
-
You can save the first lines by using this. $timestamp = $page->getUnformatted("week_begin");1 point