Leaderboard
Popular Content
Showing content with the highest reputation on 10/30/2013 in all areas
-
In this tutorial we make a simple function that becomes part of every PageArray. Once hooked to the PageArray class, you can call this function from anything returned from $pages->find(), $page->children(), or your own page references like $page->categories from the blog profile, etc. It essentially becomes a new function available to you from any PageArray anywhere in your site. First, lets look at what convenience the hook function adds and how we might use it. We'll call the hook function "renderLinks", but you could of course call it whatever you wanted. We call that renderLinks() function from any PageArray, and it returns a string representing that PageArray as a list of links. By default, this renderLinks() functions separates each page with a comma, and outputs the page's title as the anchor text. We can change that to be anything by specifying arguments to the call. The first argument is the delimiter, which defaults to a comma ", " if not specified. The second argument is the name of the field to output, which defaults to "title" if not specified. Next are 3 examples of how this renderLinks hook function could be used. Usage Examples: Example 1: render a comma-separated list of links: echo $pages->find("parent=/")->renderLinks(); Output: <a href='/about/'>About Us</a>, <a href='/contact/'>Contact Us</a>, <a href='/site-map/'>Site Map</a> Example 2: render a <ul> of $categories links: <ul> <li> <?php echo $page->categories->renderLinks('</li><li>', 'title'); ?> </li> </ul> Output: <ul> <li><a href='/categories/category1/'>Category 1</a></li> <li><a href='/categories/category2/'>Category 2</a></li> <li><a href='/categories/category3/'>Category 3</a></li> </ul> Example 3: render a breadcrumb trail: <p class='breadcrumbs'> <?= $page->parents->renderLinks(' / ') ?> </p> Output: <p class='breadcrumbs'> <a href='/parent1/'>Parent 1</a> / <a href='/parent1/parent2/'>Parent 2</a> / <a href='/parent1/parent2/parent3/'>Parent 3</a> </p> Those examples above show some of the potential of how you might use such a function. Next is the hook function itself. In order to be available to all templates in your site, it needs to be defined somewhere consistent that is always loaded... Where to put the hook function: If using the basic profile (that comes with ProcessWire) you could put the hook function at the top of your /site/templates/head.inc file. If using the Foundation or Skyscrapers profile, you could put the hook function in your /site/templates/_init.php file. This is the method that I use. If using something else, you could create a /site/templates/_init.php file with your hook function(s) in it, and then edit your /site/config.php to point to it with the $config->prependTemplateFile = '_init.php'; so that it is automatically loaded on every request. Note that the name "_init.php" is not required, you can name it whatever you want. You could put it in an autoload module... but that might be overkill here. The actual hook function: wire()->addHook("PageArray::renderLinks", function(HookEvent $event) { // first argument is the delimiter - what separates each link (default=comma) $delimiter = $event->arguments(0); if(empty($delimiter)) $delimiter = ", "; // second argument is the property to render from each $page (default=title) $property = $event->arguments(1); if(empty($property)) $property = "title"; // $out contains the output this function returns $out = ''; // loop through each item in the PageArray and render the links foreach($event->object as $page) { $value = $page->get($property); if(!strlen($value)) continue; // skip empty values if(strlen($out)) $out .= $delimiter; if($page->viewable()) { // if page is viewable, make it a link $out .= "<a href='$page->url'>$value</a>"; } else { // if page is not viewable, just display the value $out .= $value; } } // populate the return value $event->return = $out; }); If using PHP before 5.3, or using an older version of ProcessWire, you'll need to change the first line to this (below). This syntax also works with newer versions as well, but it's not as pretty as the new syntax. wire()->addHook("PageArray::renderLinks", null, 'hookRenderLinks'); function hookRenderLinks(HookEvent $event) {11 points
-
You can detect whether the current page was loaded from ajax by checking the value of $config->ajax from your template file: <?php if($config->ajax) { // page was requested from ajax } Following that, you will likely want to render the page differently to accommodate whatever you are doing from the javascript side. For instance, you might want do one of these: 1. Deliver alternate or reduced markup when loaded from ajax 2. Deliver a JSON or XML string for parsing from javascript Below are examples of each of these scenarios. 1. Deliver alternate or reduced markup when loaded from ajax You might find checking for ajax helpful when you want portions of pages to load in your site without re-rendering the entire page for each request. As a simple example, we'll use the default ProcessWire site and make it repopulate it's #bodycopy area when you click a page in the top navigation. (To use this example, you'll need the default ProcessWire site templates, though you can easily adapt the example to another situation.) To accomplish this, we'll update our main page template to only include the header and footer markup if the page is NOT being loaded from ajax: /site/templates/page.php <?php if(!$config->ajax) include("./head.inc"); echo $page->body; if(!$config->ajax) include("./foot.inc"); Next we'll update the top navigation to do ajax loads of the pages when the client has javascript (and leave as-is when they don't). Paste this javascript snippet before the closing </head> tag in the header markup file: /site/templates/head.inc: <script type="text/javascript"> $(document).ready(function() { $("#topnav a").click(function() { $("#topnav a.on").removeClass('on'); // unhighlight selected nav item... $(this).addClass('on'); // ...and highlight new nav item $("#bodycopy").html("<p>Loading...</p>"); $.get($(this).attr('href'), function(data) { $("#bodycopy").html(data); }); return false; }); }); </script> Now when you click on any page in the top navigation, it pops into the bodycopy area without a page load visible from your browser. And all pages remain accessible from their URL as well. Note that this is just a test scenario, and I probably wouldn't use this approach for the entire bodycopy area on a production site (it would make bookmarking difficult). But this approach can be very useful in the right places. 2. Deliver a JSON or XML string for parsing from javascript Lets say that you want pages in your site to return a JSON string with the page's id, title, and number of children when it is requested from ajax. When not requested from ajax, they will return their content as normal. To handle the ajax requests, you'd want to add something like this at the top of your template file before any other output. <?php if($config->ajax) { // this is an ajax request, return basic page information in a JSON string $json = array( 'id' => $page->id, 'title' => $page->title, 'numChildren' => $page->numChildren ); echo json_encode($json); return; } // not ajax, continue with regular page output And here is some markup and inline javascript you might use to test the ajax call on some other page (or the same one if you prefer). You would paste this snippet right in your site's markup where you want that info to appear. <ul id='info'></ul> <script type='text/javascript'> var url = '/'; // this is homepage, so replace '/' with page URL you want to load JSON from $(document).ready(function() { $.getJSON(url, function(data) { $.each(data, function(key, value) { $("#info").append("<li>" + key + ": " + value + "</li>"); }); }); }); </script> The above snippet would output something like this: • id: 1 • title: Home • numChildren: 5 To take this example further, you could build an ajax-driven sitemap or any number of web services. Conclusion Hope this helps you to see how simple it is to use ProcessWire to deliver output for ajax. These are just contrived examples, but hopefully examples that might lead to more ideas. In addition, much of what you see in these examples is also applicable to building web services in ProcessWire.2 points
-
If it's just one page that you have that situation on, then you can check for the page in the _main.php file and bypass the usual output, i.e. _main.php <div id='content' class='row'> <? if($page->id == 1): // homepage ?> <div class='large-12 columns'> <?=$body?> </div> <? else: // regular 2-column output ?> <div class='large-8 columns'> <?=$body?> </div> <div class='large-4 columns'> <?=$side?> </div> <? endif; ?> </div><!--/#content--> For cases where I want the option of specifying something entirely different for <div id='content'> from any template, I'll setup the option to specify a $content variable. From the _init.php you set it to be blank (the default value): _init.php $body = $page->body; $side = ''; $content = ''; // add this Then in your _main.php, you check for the presence of it. When present, the usual body/sidebar layout is bypassed and you get to specify something entirely different, simply by populating the $content variable, rather than $body or $side. _main.php <? if($content): // custom $content ?> <?=$content?> <? else: // regular 2-column output ?> <div id='content' class='row'> <div class='large-8 columns'> <?=$body?> </div> <div class='large-4 columns'> <?=$side?> </div> </div><!--/#content--> <? endif; ?> From that point forward, your templates can choose to populate $body and $side, or if the layout needs are different, then populate $content instead. Here's an example of what a hero + 3 boxes below homepage template might look like: home.php $content = " <div id='content' class='row'> <div class='large-12 columns'> <img src='...' /><!-- giant hero image --> </div> </div><!--/#content--> <div id='features' class='row'> <div class='large-3 columns'> <p>Feature box 1</p> </div> <div class='large-3 columns'> <p>Feature box 2</p> </div> <div class='large-3 columns'> <p>Feature box 3</p> </div> </div><!--/#features--> ";2 points
-
hi all, new PW site launch: http://www.ohmspeaker.com/ some of the modules that were helpful or essential for this: cropimage formbuilder fredi importcsv minify piwik analytics procache batcher redirects version control template decorator modules manager page link abstractor sitemap xml admin custom pages markup simple navigation (for the sitemap) forum topics related to this site dev: Legacy Site URL redirects: http://processwire.com/talk/topic/3641-redirect-legacy-url-to-new-pw-page/ Clean up spelling: http://processwire.com/talk/topic/3519-use-api-to-spellcheck-whole-siteclean-up-spacing/ hashes in URLs on change selected product http://processwire.com/talk/topic/3496-help-with-url-param-change/ FormBuilder http://processwire.com/talk/topic/2904-how-to-redirect-by-id/ http://processwire.com/talk/topic/2821-3rd-party-send-conditionally/ http://processwire.com/talk/topic/2820-use-session-to-remember-form-selections/ Custom Menus http://processwire.com/talk/topic/2787-custom-menu-not-related-to-page-tree/ other notes: The skyscraper profile provided the example for how to get started with the advanced product search, a.k.a. the speaker finder. The standard search has been extended to show results in different categories. there is some use of Soma's word limiter for the news teaser text, and for making meta descriptions out of body fields, from this topic: http://processwire.com/talk/topic/3429-how-to-set-text-linecharacter-limits-in-templates/ the design is built on twitter bootstrap framework Fredi proved to be totally essential for the client, in being able to rapidly edit things without having to find things in the admin. This site is going to replace an existing site on a different domain (ohmspeakers.com). At some point we weren't sure if/how we would be able to handle the shopping cart element, and then found foxycart, which proved to be the best choice, very flexible, and easy to implement for this type of site. FC is hands down the simplest and easiest way (imho) we could achieve things like the legacy product pages, where there are various parts and upgrades displayed on 1 page. this version is sort of a "v1", and will be expanded/improved a lot for a v2, which would happen in about 4 months.. BTW - these speakers are really good; i now own 3 pairs ... they look great and do sound totally amazing...! -marc1 point
-
Hi all, we lauched this big website for a festival last week, and pout a lot of work and love into this. Check out: boomfestival.org Hope you like it! and it has been received very well so far.. ( 60 000 visits in less then 1 week) It uses processwire as CMS , and I must say awesome decision to replace Wordpress we used the last editions, processwire is highly superior to wordpress as CMS . I even managed to import a lot of content from Wordpress with the Processwire bootstrap API and JSON and the help of this forum Content is loaded all with Ajax , and still backbutton does work and everything can be deeplinked . Ryan ProCache module has helped very much with Site speed and our high traffic server load If I find the time I might do a case study here...as this ajax approach moight be interesting for other developers1 point
-
I recently completed a website that had a very large gallery requiring multiple albums (categories) and 100+ images per album with pagination. The solution I developed accomplishes this with just 2 templates (gallery-index and gallery-album) and a single multi-image field for each album, allowing for quick, mass upload of images*. One of the great things about ProcessWire is that you can custom build something like an image gallery with just the tools that the template system and API provide out of the box, without going in search of modules. Once we have the basic templates set up, we will use the excellent FancyBox jQuery script/plugin to add some slick Javascript "lightbox" functionality on top of it. The gallery will still work without FancyBox or with Javascript disabled; it will simply fall back to opening each image in a blank page. So, without further ado... 1. Create a file named gallery-index.php in your site/templates/ folder with the following code. This will be the main page of your gallery. The code simply loops through all of the photo albums that are children of your main gallery page and uses the first image in the album as the cover photo: <? include("./head.inc") ?> <? // Configure thumbnail width/height $thumbWidth = 250; $thumbHeight = 250; // Create an array of the child pages that use the gallery-album template $albums = $page->children('template=gallery-album'); ?> <h2><?= $page->title ?></h2> <div class="gallery"> <ul class="gallery-row row"> <? if(count($albums) > 0) { foreach($albums as $album) { // Grab the first image from the album and create a thumbnail of it $thumb = $album->images->first()->size($thumbWidth, $thumbHeight); ?> <li class="col span4"> <div class="gallery-album photoShadow"> <a href="<?= $album->url ?>" class="gallery-albumThumb" title="<?= $album->title ?>"> <img src="<?= $thumb->url ?>" alt="<?= $thumb->description ?>" /> <h4 class="gallery-albumTitle"><?= $album->title ?></h4> </a> </div><!-- /gallery-album --> </li><!-- /col --> <? } } ?> </ul><!-- /gallery-row --> </div><!-- /gallery --> <? include("./foot.inc") ?> 2. Add the gallery-index template in the ProcessWire admin under Setup->Templates. This template does not require any fields, although you may want to add a body field for outputting additional content to the page. 3. Create a file named gallery-album.php in your site/templates/ folder. This template will be used to both hold and display the images in your albums. Here we will be loading the fancybox plugin as well, so make sure you've downloaded it here: http://fancyapps.com/fancybox/ and uploaded the /fancybox/ folder to your site/templates/scripts/ folder. We are appending the fancybox files to the $config->scripts and $config->styles array before outputting them in our head.inc file so that we're only loading that code on the album pages. So make sure you are outputting those arrays in the <head></head> section of your head.inc file along with your other scripts & styles, like so: <? foreach($config->scripts as $file) { ?><script type="text/javascript" src="<?= $file ?>"></script> <? } ?> <? foreach($config->styles as $file) { ?><link rel="stylesheet" type="text/css" href="<?= $file ?>" /> <? } ?> Please note that you will also have to include jQuery in your head.inc file before your other scripts, if you're not already including it. So here is our gallery-album.php. Notice also that we are calling the FancyBox script and customizing some of its options at the bottom of the file: <? $config->styles->append($config->urls->templates . "scripts/fancybox/jquery.fancybox.css"); $config->styles->append($config->urls->templates . "scripts/fancybox/helpers/jquery.fancybox-thumbs.css?v=1.0.7"); $config->scripts->append($config->urls->templates . "scripts/fancybox/jquery.fancybox.pack.js"); $config->scripts->append($config->urls->templates . "scripts/fancybox/helpers/jquery.fancybox-thumbs.js?v=1.0.7"); // Configure thumbnail width/height & number of photos to display per page $thumbWidth = 150; $thumbHeight = 150; $imagesPerPage = 32; // Make ProcessWire pagination work on the images field (see for full explanation of this) $start = ($input->pageNum - 1) * $imagesPerPage; $total = count($page->images); $images = $page->images->slice($start, $imagesPerPage); // Create a new pageArray to give MarkupPagerNav what it needs $a = new PageArray(); // Add in some generic placeholder pages foreach($images as $unused) $a->add(new Page()); // Tell the PageArray some details it needs for pagination $a->setTotal($total); $a->setLimit($imagesPerPage); $a->setStart($start); include("./head.inc") ?> <?= $a->renderPager() ?> <div class="upOneLevel"><a href="<?= $page->parent->url ?>">← Albums</a></div> <h2><?= $page->title ?></h2> <div class="album"> <ul class="album-row row"> <? if(count($images) > 0) { foreach($images as $image) { $thumb = $image->size($thumbWidth, $thumbHeight); ?> <li class="album-photo darkenOnHover col span3"> <a href="<?= $image->url ?>" rel="fancybox-gallery" class="fancybox" title="<?= $image->description ?>"> <img src="<?= $thumb->url ?>" alt="<?= $thumb->description ?>" /> <!-- Uncomment this line if you want descriptions under images <p class="album-photoDescription"><?= $image->description ?></p>--> </a> </li> <? } } ?> </ul><!-- /album-row --> </div><!-- /album --> <div class="group"><?= $a->renderPager() ?></div> <script type="text/javascript"> $(document).ready(function() { $(".fancybox").fancybox({ prevEffect : 'elastic', nextEffect : 'elastic', loop : false, mouseWheel: true, helpers : { title : { type: 'outside' }, thumbs : { width : 100, height : 60 } } }); }); </script> <? include("./foot.inc") ?> 4. As we did before, add the gallery-album template in the ProcessWire admin. Assign the images field to it, and go into the URLs tab and make sure Page Numbers are allowed. 5. Create a page in the ProcessWire admin for the gallery index using the gallery-index template. You'll probably want to give it a title like "Gallery". 6. Underneath your Gallery page, create child pages that use the gallery-album template, one page for each album you want to create. Name them however you'd like. 7. Go into each album page you created and populate the Images field with your images. Just drag-and-drop. It's as simple as that! If you want to add a description for each image, you can also add it here. If you have more than 32 images (or whatever value you set the $imagesPerPage variable to), the pagination will kick in and split the album into multiple pages. 8. Finally, add in the CSS. The CSS is really up to you, but I'm including a good starting point below. This includes a handy responsive grid system I built for my sites, as well as a .photoShadow class I developed which gives your album covers a cool 3D Polaroid look using pure CSS. /********* Helper Classes **********/ .row:after, .group:after { content: ""; display: block; height: 0; clear: both; visibility: hidden; } .row { ; /* Remove left gutter */ margin-top: 0; margin-right: 0; margin-bottom: 0; padding: 0; zoom: 1; /* IE7 */ position: relative; } .col { display: block; float:left; margin-left: 2%; /* Gutter size */ margin-top: 0; margin-right: 0; margin-bottom: 0; padding: 0; zoom: 1; width: 95.99999999996%; } .span1 {width: 6.33333333333%;} .span2 {width: 14.66666666666%;} .span3 {width: 22.99999999999%;} .span4 {width: 31.33333333332%;} .span5 {width: 39.66666666665%;} .span6 {width: 47.99999999998%;} .span7 {width: 56.33333333331%;} .span8 {width: 64.66666666664%;} .span9 {width: 72.99999999997%;} .span10 {width: 81.3333333333%;} .span11 {width: 89.66666666663%;} .span12 {width: 97.99999999996%;} .photoShadow { position: relative; border: 5px solid #fff; background: #fff; -moz-box-shadow: 0px 0px 2px #ccc; -o-box-shadow: 0px 0px 2px #ccc; -webkit-box-shadow: 0px 0px 2px #ccc; -ms-box-shadow: 0px 0px 2px #ccc; box-shadow: 0px 0px 2px #ccc; } .photoShadow:before { z-index: -1; content: ""; display: block; position: absolute; width: 104%; height: 16px; bottom: -5%; left: -2%; overflow: hidden; border-radius: 50% 50% 0 0; box-shadow: inset 0px 8px 5px #999; } .darkenOnHover { opacity: .8; -webkit-transition: opacity .2s; -moz-transition: opacity .2s; -ms-transition: opacity .2s; -o-transition: opacity .2s; transition: opacity .2s; } .darkenOnHover:hover { opacity: 1; -webkit-transition: opacity .1s; -moz-transition: opacity .1s; -ms-transition: opacity .1s; -o-transition: opacity .1s; transition: opacity .1s; } /********** Blocks **********/ .gallery { } .gallery-album a:hover { text-decoration: none; } .gallery-albumTitle { font-size: 1.1em; text-align: center; margin: .2em ; } .gallery-album { -webkit-transition: all .2s; -moz-transition: all .2s; -ms-transition: all .2s; -o-transition: all .2s; transition: all .2s; } .gallery-album:hover { -webkit-transition: all .2s; -moz-transition: all .2s; -ms-transition: all .2s; -o-transition: all .2s; transition: all .2s; -webkit-box-shadow: 0 0 3px #555; -moz-box-shadow: 0 0 3px #555; -ms-box-shadow: 0 0 3px #555; -o-box-shadow: 0 0 3px #555; box-shadow: 0 0 3px #555; } .album-photo img { margin-bottom: 6px; border: 1px solid #ddd; } .upOneLevel { font-size: 1.1em; margin-bottom: .4em; } .upOneLevel .icon-circle-arrow-left { font-size: 1.5em; margin-right: .4em; } .upOneLevel a:hover { text-decoration: none; } .MarkupPagerNav { margin: 1em 0; font-family: Arial, sans-serif; float: right; } .MarkupPagerNav li { float: left; list-style: none; margin: 0; } .MarkupPagerNav li a, .MarkupPagerNav li.MarkupPagerNavSeparator { display: block; float: left; padding: 2px 9px; color: #fff; background: #2f4248; margin-left: 3px; font-size: 10px; font-weight: bold; text-transform: uppercase; } .MarkupPagerNav li.MarkupPagerNavOn a, .MarkupPagerNav li a:hover { color: #fff; background: #db1174; text-decoration: none; } .MarkupPagerNav li.MarkupPagerNavSeparator { display: inline; color: #777; background: #d2e4ea; padding-left: 3px; padding-right: 3px; } I think that's it! Just make sure you're including the CSS file in your head.inc inside the <head></head> tags and you should be all set. If you come across any issues trying to implement the above (or find any of it confusing) please let me know below. Everyone is coming from different backgrounds and different experience levels. And if you find this tutorial useful, please feel free to let me know as well * I should mention that although it is possible to create galleries in Processwire where each image is represented by its own page (and, as Ryan has mentioned, is often preferable since it is ultimately more scalable), sometimes the ease of using a single image field (which can upload and decompress zip files of images in mass) simply outweighs any drawbacks. If I had to create this gallery with the 1-image-per-page method, it would have taken hours to upload all of the images one-by-one without some sort of additional programming to automate the process.1 point
-
Hi there, just gone thought this tutorial and find some glitches that may trap some people. Since I don't have a wiki account, I would like to point it out here. In the section 'Installing JQuery and Plugins' the script reference have a wrong path. The folder processWire used are scripts and styles ,not js and css In the section 'Function albumShow()', script reference at Line 64, the variable missed a 'n'. The correct line should be $thumbsize = wire("page")->gallery_thumbnail_size; Hope improvement in wiki can be carried out and help more people to learn processWire1 point
-
Hello, I've recently updated a showcase website for (private) antique collection. http://agcat.net/ Module I used: - Procache - Batcher This website is expected to be written in Japanese/English, but English texts are not available yet. Developing this website, I thought Processwire would be a fantastic solution to organise and show cultural heritage such as museum collections!1 point
-
Thanks Adrian, that's a relief to know that PW can handle millions of pages. I'm not just logging transactions, I'm currently logging whole activity, every page visited. So I guess for now I'll keep it in text files. Later once I'm more confident about the system & won't need usage report, I'll just track transactions. About the module, yes I suppose I should discuss the problem with diogo. Thanks again, have a great weekend.1 point
-
Thank you guys! Well I´ve beefed up my memory_limit to 1024M in php.ini (was at 128M), now I can upload half a dozen of those at the same time... ...just as a test. In reality it´s kind of dumb to upload giant images just for them to be re-sized, but I have users who have never used any image manipulation software and just plug in their digital camera... I wonder where the possible disadvantages might be of upping the memory limit like that, I guess I could set it even higher... (assuming my hosting environment doesn´t prohibit it;-)1 point
-
http://processwire.com/talk/topic/3388-question-about-headinc-and-footerinc/ head and foot.inc start to make sense only after getting used to pw, maybe they need to be introduced more beginners friendly.1 point
-
I bet if you open those images in photoshop the larger image would use more RAM than the smaller. With jpg's the file size can foul you.1 point
-
Maybe you have some other request (iframe, ajax loading, something?) that is happening behind the scenes. Maybe add $_SERVER['REQUEST_URI'] to your log?1 point
-
Another update - things are getting closer! I have just added support for migration of the selected values of page fields when migrating "everything, including all data pages". Only repeater field page data (the fields, templates etc are already working) to go, and then of course the inevitable bugs EDIT: Just found a bug in the page field data migration - hopefully solve this soon. Repeater data is working now though - not on github yet, but I will push that too once I have the page field issue sorted out.1 point
-
In your php.ini file, look for the memory_limit setting and increase that as needed.1 point
-
1 point
-
Hello ioio, Welcome to the ProcessWire community! Don't be afraid of messing the admin part of ProcessWire as long as you touch templates in the site/templates/ directory of your installation. You can indeed use the same names head.inc and foot.inc even though you change all their content. The Admin part is left clean because it resides in the wire/ directory and you don't want to touch this one ;-) Actually, this is my first answer to someone's question! No doubt another member of the community will provide you with useful recommendations. Hope I helped ! EDIT : Woa... You guys are so fast...1 point
-
Hi ioio, welcome to the forum! You can replace them without any problem. Actually, you can replace everything in the templates folder by your own files without any problem with the exception of admin.php. Just be aware that ProcessWire will look on that folder for the php files that correspond to the names of your page templates. You can also replace the scripts and style pages and organize your includes inside your own folder structure, as long as you call them with the correct path on the include() function. Edit: Adrian was faster because Canada is closer to the PW server than Portugal Edit: On the other hand, Portugal is closer than France and Switzerland1 point
-
Hi ioio and welcome to the forums. You can edit anything under the site/templates folder without affecting the admin side of PW. Let us know how it works out with the head and foot files and if you have any more specific questions. Also, not that you don't even need to follow the structure of having a head and foot file. Many users prefer a main.inc file which contains the entire site structure and echos the content variables where appropriate and is included at the end of each template file. There are other possible approaches as well - really it just comes down to what works best for you and how you like to work and mentally visualize things.1 point
-
1 point
-
Just for the record: I'll consider using a captcha, blacklist etc. once honeypots (regular or reverse) start failing me. So far they've provided better results than any other solution -- and all that without breaking UX.1 point
-
Hello there, and welcome to the forum! To answer your last question: yes, it should work. This seems like a strange one, I can't seem to spot the issue right away. It kind of sounds like there was a case where job_image->first() returned nothing (or, at least, something other than an object). Is there a single call to that function in this page and you're sure that the target page has an image? You're not by any chance iterating over multiple pages and outputting their content? It'd be helpful to know what exactly is returned: $firstimage = $finalarrayitem->job_image->first(); // get the type of returned value echo gettype($firstimage); // if it's an object, see if it's a Pageimage if (is_object($firstimage)) echo " " . get_class($firstimage); Of course you could also try doing var_dump($firstimage), but for larger objects that's somewhat difficult to read1 point
-
Hi! I'm no php expert but I thought I should share my way of redirecting URLs from my old site setup. I'm going to use Drupal urls in this example, but should work for any url. I can't guarantee this is the best way of doing it, so please feel free to correct me if you have feedback regarding security, speed or similar. Step 1: Make sure that each page in PW has some kind of connection to its previous URL so it can recognize when a redirect needs to be done. I'm going to use the node id:s and taxonomy id:s that my pages had when they were located in Drupal. I've made sure to save them all into each processwire page in a field called "drupal_id". Maybe you could just save the old URL in a field when migrating and use that, as an alternative. Step 2: Open head.inc and add this to the very top: $thisurl = $sanitizer->url("http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"); // Check if the URL reminds you of the old url scheme if (preg_match("/com\/\?q=/", $thisurl)){ // if it looks like a node url if (preg_match("/\?q=node\/[0-9]*/", $thisurl, $nodeslug)){ $oldnid = preg_replace("/\?q=node\//", "", $nodeslug[0]); if ($match = $pages->get("drupal_id={$oldnid}")){ $session->redirect($match->httpUrl); } else { $session->redirect($config->urls->root); } // If it's a taxonomy url } elseif (preg_match("/\?q=taxonomy\/term\/[0-9]*/", $thisurl, $taxonomyslug)) { $oldtid = preg_replace("/\?q=taxonomy\/term\//", "", $taxonomyslug[0]); if ($match = $pages->get("drupal_id={$oldtid}")){ $session->redirect($match->httpUrl); } else { $session->redirect($config->urls->root); } } else { $session->redirect($config->urls->root); } } Regex is used to find URL schemes and extract drupal nids and tids from the url. These are then looked up using the api, only to return the new url. Each time the url redirect fails, it might be suitable presenting a warning to the user. I've added something like $session->message("This URL seems to have changed. Please use the search if you didn't find what you were looking for") on the line before redirect (not part of the code example above, for simplicity's sake). Hope this can be useful for someone else, too. And again, feel free to leave feedback! I'm here to learn, too1 point
-
Adrian, thanks for posting the links to that topic. But taking a look at the code i see its not realy a solution. I think it will not work when having multiple color pickers in one template. The thing is that the colorpicket swatch work fine in the default admin template. But stop working in the new admin template. I have taken a closer look and see that the solution Pete has posted is working great http://processwire.com/talk/topic/4650-new-processwire-admin-theme-on-dev-branch/?p=46380 I have modified the javascript from the colorpicker module and it works now great on the "old" and "new" template aswell. And made a pull request on GitHub for soma. Thanks guys!1 point
-
Arcturus, Go to Modules > Process > Users. It should let you select what fields you want to be shown in the listing, and in what order. As for changing the name of the "name", I don't think you can do that short of going through a hook or using the multi-language translation system (and translating the default language value). If you want to do that, the file where it is located is /wire/modules/Process/ProcessPageType/ProcessPageType.module in the renderList() method. Of course, you could just change it directly in that file, but your change would get overwritten during upgrades, so you'd need to remember to change it again.1 point
-
Realy nice this module. I noticed when using the "Hanna Code Text Formatter" to output a field that has also "Hanna Code Text Formatter" you need to set Output Filtering to false at some point. In my example i wanted to output the page title of multiple pages, while the page title itself also had the "Hanna Code Text Formatter" attached. Then it would show only the last title. Edit: i just see that this is kinda what Ryan mentioned 2 posts before. echo $child->getUnformatted('body'); The following works also, thats what i am using, but i suppose its the "same same, but different": $child->of(false); echo $child->body;1 point
-
For efficiency reasons, Textformatter modules run from a single instance, so I'm guessing this is a side effect of that. I'll look into options for how we might get around the issue the next time I'm making updates to it. But assuming that 'body' is a rich text field and Hanna Code is the only Textformatter you had on it, you could probably get the unformatted version of it from your Hanna code and use that instead, to avoid triggering the circular reference (or whatever it's called). echo $child->getUnformatted('body');1 point
-
Hi folks I thought I'd post up a quick, basic tutorial of how to get started with Github and not have to learn any of the command line code. It's still recommended that you learn the basic commands, but this is aimed to help Git newbies like me get their modules on Github with the minimum effort possible. Check out the PDF below and have fun GitHub for Windows.pdf1 point
-
Asana's great but if you don't have enough people using it properly it ends up being one of those things you drop and end up going back to more traditional means (pen & paper). I still hope to get there but it's hard pushing a system when the other people don't want to know1 point
-
Greetings, I felt a needle-like pain in my head, and wondered where it was coming from... Ah, there it is -- Joomla and Artio. All jokes aside, it is true that in Joomla there are ready-made components that take care of a whole range of actions. But then you have to override what you don't want or need, wage mortal battles where various pieces of baked-in Joomla code conflict with your modules and plugins, and spend hours trying to get a developer's attention long enough to figure out where in the world they placed the code for a particular action you need to customize, and why they put it there. And let's not forget that no Joomla component can be used without... Joomla! Which means you are also inheriting its migraine-inducing template system, admin area, lack of custom fields, mind-numbing dummy menu entries and plugin ordering (Joomla people will know what I mean by these last two). OK, let me take a breath... I understand the idea of using something that has "been done already." But since I started using ProcessWire, in all seriousness, it takes me less time to create something from scratch than to wrangle with any of Joomla's "ready-made" code. Two better ways to go: 1. Get part-by-part help from the community 2. Find ready-made JQuery, PHP, and other components that can hook into ProcessWire Thanks, Matthew1 point