Leaderboard
Popular Content
Showing content with the highest reputation on 06/27/2016 in all areas
-
I am sure it does. But the point here is that i made something because i wanted to try it with PHP and to do one thing very good. Not everything has to be a module. This script is not meant to be a swizz army knife. The point is to experiment, and share my findings so others could see have they could use PHP in different ways.2 points
-
Old topic update: here's a plain JavaScript version of the module JS for those who don't use jQuery: https://github.com/rolandtoth/EmailObfuscator/blob/master/EmailObfuscator.js2 points
-
Mexico here, can confirm everything on the Internet feels expensive ALWAYS on almost any currency2 points
-
There are probably various examples of the plain pw api usage around in the forums. I've also started this one, to allow for a user-contributed migration "snippets" directory: https://github.com/LostKobrakai/MigrationSnippets Examples on how to use the specific helper migration classes of the module can be found here: https://github.com/LostKobrakai/Migrations/tree/master/migrations2 points
-
Latest version of InputfieldSelectize(1.0.1) has some cleanup and multiple version adds support for max items.2 points
-
Foundation 6 Minimal site profile for ProcessWire This profile is based on the "minimal site profile (intermediate edition)" and bundled with Foundation 6. This precompiled version can be downloaded at github. Features Foundation 6 framework Font-Awesome MeanMenu Slick Carousel (Why not Orbit ?) Render / helper functions for : Simple ul navigation Foundation Multi-level topbar MeanMenu - Responsive menu for mobile device Slick Carousel Foundation Accordion Foundation Callouts Jumbotron Dependencies jQuery How To Install Download the zip file at Github or clone directly the repo with git clone and skip the step 2. Extract the folder site-fdn6-precompiled into a fresh ProcessWire installation root folder. During the installation of ProcessWire, choose the profile "ProcessWire Foundation 6 profile". References Foundation 6 documentation ProcessWire documentation MeanMenu documentation Slick Carousel Documentation Credits The ProcessWire staff Screenshots1 point
-
.htaccess to the rescue? Redirect 301 /home/business-directory/business-categories/ http://www.yourdomain.ext/business-directory/1 point
-
Jumplinks is your friend http://modules.processwire.com/modules/process-jumplinks/ use wildcards to define the redirect: SOURCE: /home/business-directory/* DESTINATION: /home/business-directory/1 point
-
you could do a hook that rewrites the URL for those child pages to the parent.. doing it 'all the time' in site/ready.php /** * This hook modifies the default behavior of the Page::path function (and thereby Page::url) * this will rewrite the path to children that should not have their own page * any automatic links to the page, e.g. in the admin, will direct to the parent page. * */ wire()->addHookBefore('Page::path', function($event) { $page = $event->object; if($page->template == 'sometemplate') { $event->replace = true; $event->return = $page->parent->path; } });1 point
-
I do not know why do you need it? Why not have 404 on something you don't want to show anyway? Why not have a php file to do what you need if you need it? You can build a separate page tree branch just for categories (for business-categories template pages) and connect them to end-level pages like ABC Fence with page field. In this case your end-level pages should have different template and can live under business-directory, while categories themselves are elsewhere as noted above.1 point
-
Does using dedicated module files help a lazy programmer? For a private helper module I wanted to built, I decided to use the possibilities of dedicated files (implemented in PW 2.5.5) and not to write all into a single module file. Until now, I totally missed or forgot about this possibility. To my excuse: on introduction I may have thought not to use it early in my modules to keep backward compatibility. And then totally forgot about it. I allready use a tool for postprocessing in my sites. And I'm not familiar with all those popular node/grunt/gulp/npm/bower/and-what-else stuff out there. It looks to me a bit oversized for small to medium websites. But I also wanted not miss a comfortable, easy to use config for less and sass files, especially for those from frameworks like Bootstrap 3 / 4 or UIKit. So, what my toolbox should get added was a preprocessor (compiler) for sass (.scss) files first. I choosed the UIKit for the first shot. The created files for a configurable module called PreAndPostProcessor and a process module called ProcessPreProcessor were: PreAndPostProcessor.module PreAndPostProcessor.info.json PreAndPostProcessorConfig.php ProcessPreProcessor.module ProcessPreProcessor.info.json ProcessPreProcessor.css ProcessPreProcessor.js As you can read about the differences to the old-schooled style in Ryans blog post, I focus on what I found out to be most useful for me. Starting with the Config file, I decided to use the $this->add() method in the __constructor(). It is the way what needs less code to define your inputfields for a configpage: just a collection of arrays with field or fieldset definitions. Mandatory definitions are: type, name, label. Others are optional: description, notes, required, columnWidth, collapsed, showIf, ... And, of course, you need the definitions specific to your fieldtypes (value, options, ...). To group some fields into a fieldset, add a key called "children" to the fieldset array and add all field definitions to it as collection. Simple! Another nice thing I discovered, is the use of the *.info.json files. So, this I have used before, but not like here. The behave is like with the *Config.php files, - you write really less code, just arrays with key - value pairs and PW does the rest for you! Only difference here is, that you have to write it in JSON notation. The ProcessPreProcessor.info.json file contains the neccessary and common parts: title, version, requires. And some others: permission, permissions, page and nav. Page and nav are specific to Process modules. With page {name, parent, title} you define where PW should create you a page in the admin, and with nav, you can define a complete submenu for this page. For those who are yet not familiar with the internal structure of Processmodules: you can navigate to a submenu entry by calling it: {pw-admin-url}/{main-module-url}/{submenu-url}/. Calling the main menu url invokes the ___execute() method of the module. Calling a submenu url invoke the ___executeSubmenu() method. This all is really simple and straight forward. And it is really really helpful in cases like with the new toy for my toolbox. The nav is a collection of arrays, each holding at least an url and a label. Thats enough for PW to implement the menu and submenu for you in the admin. But you also may define an icon too. Aaaand, you also can add your own custom key / value pairs to it. PW does not complain on it. I have added a description. The nav was generated by parsing all core distribution scss files from the UIKit. They have a name and description in their first two lines. I programatically read this out and generated this nav notation for the info.json file: The (main) ___execute() method of the ProcessPreProcessor.module should present a submenu list with file infos. This now could be done by parsing the info.json file: public function ___execute() { // generate a navigation $dump = json_decode(file_get_contents(dirname(__FILE__) . '/' . basename(__FILE__, '.module') . '.info.json')); $nav = $dump->nav; $out = "\t\t\t<dl class='nav hnpp'>\n"; foreach($nav as $obj) { $out .= "\t\t\t\t<dt><a href='./{$obj->url}'>{$obj->label}</a> ></dt>\n"; $out .= "\t\t\t\t<dd>{$obj->description}</dd>\n"; } $out .= "\t\t\t</dl>\n"; return $out; } To make it even more friendly for lazy devs, , I created one method that is called from all sub-execute methods by simply passing their own name over into this function that loads and parse the scss file and displays its config page: The first version work out nicely. Here is a screenshot of it: ... and to answer the initial question: Yes, it does!1 point
-
Hi Xonox, You could create a new PageArray and append the pages without the training start time at the end: $today = time(); $parent = $pages->get('/formacao/'); $trainings = $pages->find("parent=$parent, template=training, limit=6, !training_start<$today, sort=training_start"); $_trainings = new PageArray(); $empty = new PageArray(); foreach ($trainings as $training) { if ($training->training_start) { $_trainings->add($training); } else { $empty->add($training); } } $_trainings->import($empty); I'm sure there are more elegant solutions1 point
-
1 point
-
It depends. I'm mostly using templates and tree/branch relationships between pages to select (other) pages. Paths are also good if you're really sure they stay consistent. I'm using ids really only if I have to (e.g. alternative user parent). In the end not using ids is also more descriptive – it's like it's with magic numbers in programming. And it's a lot more resilient. If someone does accidentally delete a page the id is gone, whereas any other selector will just work as soon as you recreate that page. Edit: And the point, which is more in context to the topic. As soon as production and local development are running in parallel you can either not rely on ids or you have to (probably manually) edit every new id reference in your code on deployments, which has the not so nice side-effect of bringing your codebase out of sync.1 point
-
What are you suggestions about it? Only use selectors based on path?1 point
-
In the ideal case you're not keeping log, but rather you make the local changes only via migration files in the first place. The actual number of those does not really matter as long as it's in logical steps. It might seem like a lot of extra work, but it really is – after creating a few of those – more a case of copy&pasting and adjusting a few key points. And the time saved when actually deploying changes is a lot. It makes the whole update process a lot more transparent and less error prone. I'd strongly suggest you to not hardcode/rely on any page IDs in your app (besides maybe ID 1 and 2). They'll get out of sync faster then you can keep track of it. The idea of separating tables might seems like a nice solution, but it would probably need a lot lot of core hacking to make that happen. Also it's not just the 'pages' table, but you'd need to split any field's table as well. It might work somehow, but I imagine it to be not worth the hassle and the inflexibility. I'm not really recommending anythings. Migrations work great for me, but every use-case is different.1 point
-
So after some hours of testing/research/code experiments, that yielded the modifications I made to the module as noted on GitHub, i can now send messages with the ability to switch between the sending domain and it all works. (also see edited post above). Goodbye Mandrill!1 point
-
I've just gone ahead and added such a repo to GitHub: https://github.com/LostKobrakai/MigrationSnippets. Maybe this can also serve as a resource for people, who are not sure they understand what this module does provide. I've already added 2 example cases. I think over time I'll add some more, but everyone is welcome to add their files as well.1 point
-
My module does not really do anything on it's own. It's more a managing helper for handling/running those migration files. Any actual changes you'd write on your own using the processwire api (in those files). It's like you would have done these changes in the backend, but it's done by code. There are some helpers included to reduce the amount of verbose code, but that's about it. With the processwire api at hand you'll probably not even need to think about the db, which is probably the biggest difference between something like phinx or other frameworks' migration files to the ones my module does handle. You'll not manually add any new tables or columns. You'll just add a field to a template or create a new page or something. If you've handled all local changes using those migration files you can just put those on the production server and run them there as well. If everything went well all your changes should be applied as they were locally. Just keep in mind the module is not making any backups of sorts. This is the users responsibility. Your points about db dumps are certainly valid, but it just is the case, that almost everything in pw is a page, even users. There's no point in working against this. E.g. how should pw know which users where created by you locally and which one online in the production system? Same for normal pages. How should pw devide between a list of countries you added as pages for a select field and some other pages, which represent dummy user content you work with locally, but are not to be migrated. Especially in a dynamic structure like the pagetree where things can be moved around super easily and templates can also be changed as fast there's no point in even trying to separate out anything.1 point
-
Man Google is such a nice service provider. I cannot imagine how many google maps implementations they broke just by applying policy changes "as of now". I mean I didn't like instagrams move to only "approved apps", but at least they told people about is half a year beforehand.1 point
-
If you're using flexbox for plain alignment issues, where things just don't look as nice and tidy on old browsers there's no need to care about a polyfill. For creating grids and such things flexbox isn't really designed for and I'd simply stay with the good old float or inline-block tools. Css grids, which are really created to solve the grid issues, are sadly still way from being supported widely.1 point
-
I played with flexbox and tried to use it. Works fine with modern browsers, but IE10 doen't work (should support old syntax...) can't get flexibility work (IE 8/9 flexbox support) Thanks for the link https://github.com/StefanKovac/flex-layout-attribute. Looks nice and simple. Because of my tests I created an simple flexbox css file which seems to work fine with modern browsers and also allow nested flexboxes, but without IE <=10 support1 point
-
The problem – as you're describing it – is trying to separate user-content from otherwise bootstrapped content. That's just not how it works. It's all content in pages and processwire does not care where it came from. You might set templates up to be only single use or other things, but in the end it's all pages. So you probably should not try to work/hack around that. Also db backups and dumps are almost never a sane way to update a production site as soon as any content is independently created on it, be it user or only client/editor changes. It's hardly a processwire specific problem. If you need things to not be manual updates you've probably not many more options than these. The common way for other web frameworks out there to have is to use migration files, which are files handling any "bootstrap" changes in the db and as they're files they simply are tracked by any used VCS and just run on each deployment. I've created a module to use this strategy with processwire: There's also a migrator module from adrian, which tries to solve the "migrating pages / templates / fields" issue, but I'm not sure if it can handle e.g. changes of module settings or installing new modules and such things: You could also look in non pw-specific migration tools like https://phinx.org/, but hand writing pw changes in mysql queries might not be fun. There's also this tool, which claims to track db changes, but I'm not sure how well it does work: http://dbv.vizuina.com/.1 point
-
Have you come across this in your travels? http://flexboxfroggy.com/ I thought it was a funny drill to get familiar the various flex settings. Also came across this write up https://css-tricks.com/snippets/css/a-guide-to-flexbox which looked like a good read and reference.1 point
-
Here is another way you can get your repeater items, by first finding the pages those repeaters are on. Not tested. <?php // sanitized input $types = $sanitizer->selectorValue($input->get->type); $patterns = $sanitizer->selectorValue($input->get->pattern); $designers = $sanitizer->selectorValue($input->get->designer); $colours = $sanitizer->selectorValue($input->get->colour); // selector $selector = "template=template_with_repeater_field, collections_detail_images.count>0, sort=title"; if ($types != "all") $selector .= ", collections_detail_type=$types"; if ($patterns != "all") $selector .= ", collections_detail_pattern=$patterns"; if ($designers != "all") $selector .= ", collections_detail_designer=$designers"; // here we make sure we only find pages that have the right colour in one of their repeater items if ($colours != "all") $selector .= ", collections_detail_images=[collections_detail_image_colour.collections_colours_group=$colours]"; $results = $pages->find($selector); include './collections-filters.inc'; // not sure what this does ?> <?php if(count($results)): ?> <div class="container-fluid"> <div class="row"> <div class="fabric-list-container collections-results all"> <?php foreach($results as $result) { $fabrics = $result->collections_detail_images; $fabrics->sort("collections_detail_image_colour"); if($colours != "all") { $fabrics->filter("collections_detail_image_colour.collections_colours_group=$colours"); } foreach($fabrics as $fabric) { include './fabrics-list.inc'; } } ?> </div> </div> </div> <?php endif; ?> Another thought: seeing as you want to do all this stuff with your repeater items outside the context of them being fields in another page maybe repeaters are not the ideal mechanism for your data. Could these repeater items instead be normal pages, related to their 'get-for' pages either via a parent-child relationship or via a Page field in the collections_detail_images pages? You can make the collections_detail_images pages easy to add by including them in the "Add New" menus.1 point
-
There's not even the need to manually count the number. foreach($page->children->getValues() as $key => $child) { if($key % 2 == 0) { // even } else { // odd } }1 point
-
Version 0.2.3 is uploaded, and it's also available from the Modules Directory: http://modules.processwire.com/modules/admin-on-steroids/ new submodule NoAnims: disable all admin animations (CSS & JS) fix for module repository update showing "Requires 0.0.0 >= 0" (reported by matjazp) CSS fixes1 point
-
Very nice updates! I wish you worked more on mutilanguage sites to get such great improvements1 point
-
This morning's commits add to the color scheme: Red: The current page is using a different template. Orange: The current page is using it's default template file, but there are other pages on the site that are using a different template file (obviously via the Sticky option). Use "Reset All" to clear this when you're done testing. Green: All pages on the site are using their default template files. This is now documented on the blog post.1 point
-
1 point
-
@pmichaelis + @chugurk maybe my answer help both of you... i use MapMarker Field only in backend to get lat and long data from adresses and use them with leaflet cluster maps to generate frontend output from the geodata... in your main template or header add needed scripts: <!-- set extra scripts to load if there was a map on the page --> <script type="text/javascript" src="<?php echo $config->urls->templates?>theme/js/jquery.min.js" ></script> <script src="<?php echo $config->urls->templates?>theme/js/leaflet.js"></script> <script src="<?php echo $config->urls->templates?>theme/js/leaflet.markercluster.js"></script> <link rel="stylesheet" href="<?php echo $config->urls->templates?>theme/css/leaflet.css"> <link rel="stylesheet" href="<?php echo $config->urls->templates?>theme/css/MarkerCluster.css"> <link rel="stylesheet" href="<?php echo $config->urls->templates?>theme/css/MarkerCluster.Default.css"> in your template to show the map with many markers using marker cluster output you could use something like this: //set output $map = ''; $addressPoints = ''; //get all addresspoints for the JS of the MarkerCluster $items = $pages->find("template=entry, map!=''"); foreach ($items as $m) { if ($m === $items->last()) { $addressPoints .= '['.$m->map->lat.', '.$m->map->lng.', "<a title=\"'.$m->title.'\" href=\"'.$m->url.'\">read more</a>"]'; } else { $addressPoints .= '['.$m->map->lat.', '.$m->map->lng.', "<a title=\"'.$m->title.'\" href=\"'.$m->url.'\">read more</a>"],'; } } //render cluster map with all items //centered to bavaria lat/long!! //set the needed inline JS for the map content $inlineJS = " <script> var addressPoints = [$addressPoints]; var tiles = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', { maxZoom: 18, attribution: '© <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a>' }), latlng = L.latLng(48.1835,11.8570); var map = L.map('map', {center: latlng, zoom: 8, layers: [tiles]}); var markers = L.markerClusterGroup(); for (var i = 0; i < addressPoints.length; i++) { var a = addressPoints[i]; var title = a[2]; var marker = L.marker(new L.LatLng(a[0], a[1]), { title: title }); marker.bindPopup(title); markers.addLayer(marker); } map.addLayer(markers); </script> "; $map .= '<div id="map"></div>'; $map .= $inlineJS; $content .= $map; This should render a map like the developer locations map http://directory.processwire.com/map/ with marker clusters... for single marker output there should be a lot of information in the topic if you search or read for it.... https://processwire.com/talk/topic/9711-map-marker-map/page-2#entry18338 https://processwire.com/talk/topic/9711-map-marker-map/page-2#entry21061 https://processwire.com/talk/topic/9711-map-marker-map/page-3#entry28913 since post #98 you could use MarkupGoogleMap too render a map on frontend: https://processwire.com/talk/topic/9711-map-marker-map/page-5#entry41984 please read carefully before asking and provide code examples if you get stucked.... best regards mr-fan1 point
-
Hey Pete - nice one! I know your code is meant as a quick snippet to get the job done, so no offense intended, but the concerns I have with this is: On a site with a LOT of pages, that could be very slow. I don't like the fact that it re-saves every page, regardless of whether there is a change or not, which will affect the modified date and modified user. I have actually already made a start on a feature rich search and replace module which I will get around to finishing up sometime soon. It provides the ability for searching and then showing the search term in context for each match. You can then choose which matches get replaced, or replace all. Stay tuned!1 point