Jump to content

BitPoet

Members
  • Posts

    1,331
  • Joined

  • Last visited

  • Days Won

    61

Everything posted by BitPoet

  1. You mean the Schedule Pages module? That's actually possible. From a quick glimpse, it hooks before Pages::save and, if a publish_from date is set, tries to clear that and calls "$page->save('publish_from');". This line should probably only be executed if $page->isNew() returns false.
  2. Ah, I see that only now. You should be able to comment out the require_once and session_start lines in AutoFbPost.module and change the autload property in line 40 to false to stop it from interfering with your session.
  3. Never seen that. Maybe you could use Tracy Debugger to get a full stack trace that points you to where the call to $pages->saveField originates (perhaps some module?).
  4. Could it be that you replaced your site/config.php and changed $config->userAuthSalt? If yes, restoring the old value for userAuthSalt would be the preferred way to go.
  5. Did you see my correction (I had initially written "true", which, of course, doesn't change anything).
  6. Are you copying through the UI or API? If the latter, can you show the relevant snippet of code?
  7. This sounds more like a stale frontend-proxy or session caching issue than something caused by module installation. Try setting $config->protectCSRF = false; in site/config.php, then you should be able to log in again and can dig deeper into the root of the problem. Edit: meant setting it to false, of course.
  8. Also, since opcache is enabled, make sure that opcache.use_cwd is enabled. Otherwise, strange things may happen.
  9. @Alxndre', you may find some useful snippets in my Template Parents module(s) as a starting point. For historical reasons, the hooks into the Template methods for injecting the field markup and for triggering storing of the value are in TemplateParents.module, while the creation of the necessary database table and the save/load logic itself is in ProcessTemplateParents.module, but all of these could easily be combined into a single module file.
  10. Yepp, that's what I thought too about a navigation, thus the sitemap changed into a slider.
  11. For a little data visualization task at work, I (finally) got to do some tinkering with WebGL / 3D, and as a small Easter egg, I thought I'd share one of the (admittedly a bit crude) side results for anybody also new to and interested in 3D in the web. Before I went into full-blown meshes and textures, I animated DOM elements in 3D and built a little spinner to get a feel for positions, camera and the behaviour of my library of choice, three.js. Don't mind the "Sitemap 3D" title in the screencap, that was just a spur-of-the-moment thing, but what came out was a classic (static) spinner. I really love how you can move regular HTML elements through thee-dimensional space and still use all the regular CSS styling, including colors, transparency, borders and shadows. Step-by-step: Download three.js from GitHub and extract it into a folder named "three.js" in site/templates (it comes with all examples and is a bit big, but we need a few of those). Adapt the template you want to show your 3D spinner in to include jQuery, the three.js main file, CSS3DRenderer and Tween (the latter is used for smooth animations). <script src="<?= $config->urls->templates ?>three.js/build/three.js"></script> <script src="<?= $config->urls->templates ?>three.js/examples/js/renderers/CSS3DRenderer.js"></script> <script src="<?= $config->urls->templates ?>three.js/examples/js/libs/tween.min.js"></script> <?php $jq = $modules->get('JqueryCore'); foreach($config->scripts as $script) { ?> <script src="<?= $script ?>"></script> <?php } ?> Add a div with position: relative and a fixed height (fixed width is optional) in your template and give it an id (in my example I'll use "main"). Paste the following code into a php file in site/templates and include the file in your template before the closing body tag. If you gave your container an id different from "main", adapt the first parameter for the showSpinner call close to the bottom. <div id="spinnertmp"><!-- A temporary container --> <?php // Get our list of items. The first item in the PageArray is shown front center. $mainpages = $pages->find('parent=1')->and($pages->get('/'))->reverse(); $links = array(); $first = true; foreach($mainpages as $pg) { $id = "smitem_{$pg->id}"; $links[] = $id; $cls = ""; if($first) { $cls = " smactive"; $first = false; } // Our spinner items: echo " <div class='smitem$cls' id='$id'> <a href='#' class='smleft'><</a> <a class='smlink' href='$pg->httpUrl' title='$pg->title'>$pg->title</a> <a href='#' class='smright'>></a> </div> "; } ?> </div> <script> function showSpinner(el, prnt) { var camera, scene, renderer; var links = [ <?= implode(",\n\t\t", array_map(function($v) { return "'$v'"; }, $links)) ?> ]; var w, h, wInt, hInt; var objects = []; /** * On window resize, we also recalculate our camera position and set the * size of the render canvas. This last step may not be necessary if you * use a containing element with fixed bounds. */ $(window).on('resize', function(evt) { camera.position.z = w / 1.5 + 250; camera.updateProjectionMatrix(); renderer.setSize($(el).innerWidth(), $(el).innerHeight()); circle(); }); /** * Prev and next link click handlers for our spinner items */ $('.smleft').on('click', function(evt) { evt.preventDefault(); goLeft(); }); $('.smright').on('click', function(evt) { evt.preventDefault(); goRight(); }); // Get the show started, init() also calls render() init(); // Remove the no longer needed container for our spinner items from the DOM $(prnt).remove(); // Start the animation loop animate(); // Move our spinner items into a circle circle(); /** * Rotate the circle left/right by moving the first/last item * to the other end of the item stack and letting circle() * move them into the new positions. */ function goLeft() { objects.unshift(objects.pop()); links.unshift(links.pop()); circle(); } function goRight() { objects.push(objects.shift()); links.push(links.shift()); circle(); } /** * Initial setup */ function init() { $(el).css('padding: 0;'); w = $(el).innerWidth(); h = $(el).innerHeight(); wInt = ( w - 80 - 150 ) / links.length; hInt = ( h - 80 - 50 ) / links.length; camera = new THREE.PerspectiveCamera( 40, w / h, 1, 10000 ); camera.position.z = w / 1.5 + 250; scene = new THREE.Scene(); for(var i = 0, l = links.length; i < l; i++) { var $el = $('#' + links[i]); // create a CSS3DObject from each spinner item element var object = new THREE.CSS3DObject( $el.detach().get(0) ); var curpos = object.position; // for a start, let's align them all in a diagonal row object.position.x = -1 * w + 2 * (i * wInt + 40); object.position.y = -1 * h + 2 * (i * hInt + 40); object.position.z = 50 * i; objects.push( object ); $(el).append($('#' + links[i])); scene.add( object ); } renderer = new THREE.CSS3DRenderer(); renderer.setSize( w, h ); renderer.domElement.style.position = 'absolute'; $(el).append($(renderer.domElement)); render(); } /** * Arrange our items in a circle and float them to the target position */ function circle() { // Get our containing element's coordinate measures w = $(el).innerWidth(); h = $(el).innerHeight(); wInt = ( w - 80 - 150 ) / links.length; hInt = ( h - 80 - 50 ) / links.length; // Make the radius and placement angle dependant on the number of // items and the size of our canvas var l = objects.length; var radius = w / 1.5 - 200; var cX = 0; var cZ = 0; // just basic radians/degree conversion math, nothing to be afraid of var mpi = Math.PI / 180; var startRad = mpi; var incAngle = 360 / l; var incRad = incAngle * mpi; // Let's do some cleanup before the party starts again TWEEN.removeAll(); // Move every item to its new assigned position for(var i = 0; i < l; i++) { // x and z coordinates (left-right and back-front), no y needed as all stay at the same height var xp = cX + Math.sin(startRad) * radius; var zp = cZ + Math.cos(startRad) * radius; // our item's rotation as it revolves around the circle var rotY = i * incAngle * mpi; /** * A tween is a smooth transition over a given time. You pass the start values (must be numbers) * to the constructor and the desired destination values to the to() method. The property names * can in fact be arbitrary but need to be consistent between the constructor and to(). * * The onUpdate handler will be called every time a frame is ready, and the correct transition * values are set to corresponding properties of the "this" object. Assigning the passed properties * to a 3D object is the task of the developer. */ (function(mObj, twNum){ new TWEEN.Tween( {x: mObj.position.x, y: mObj.position.y, z: mObj.position.z, rotY: mObj.rotation.y } ) .to( {x: xp, y: 0, z: zp, rotY: rotY}, 1000 ) .onUpdate(function() { mObj.position.x = this.x; mObj.position.y = this.y; mObj.position.z = this.z; mObj.rotation.y = this.rotY; }) .onComplete(function() { // color only the item currently in the front (first item in our stack) differently $('.smitem').removeClass('smactive'); $('#' + links[0]).addClass('smactive'); }) .start(); // start the transition })(objects[i], i); // increment rotation for the next item startRad += incRad; } } /** * simple but magical, pushes itself onto the stack to be processed the next time * the computer is ready to draw the scene. */ function animate() { requestAnimationFrame(animate); TWEEN.update(); render(); } /** * paint it, dude! */ function render() { renderer.render(scene, camera); } } $(document).ready(function() { showSpinner('#main', '#spinnertmp'); }); </script> Style your container element and spinner items. Here's the CSS I used, but you can go all out there: #spinnertmp { display: none; } #main { height: 400px; position: relative; background-color: rgb(0,20,10); padding: 0; margin: 0; overflow: hidden; } .smitem { position: absolute; width: 200px; height: 50px; padding: 2%; border: 1px solid rgba(127,255,255,0.25); box-shadow: 0px 0px 12px rgba(0,255,255,0.5); text-align: center; left: 20px; top: 20px; background-color: rgba(0,127,127,0.40); display: flex; } .smlink, .smleft, .smright { text-decoration: none; font-size: 1.4em; font-weight: bold; color: rgba(127,255,255,0.75); display: inline-block; } .smlink { flex: 5; } .smlink:hover { color: rgba(255,215,0,0.75); } .smleft, .smright { flex: 1; } .smleft:hover, .smright:hover { color: rgba(255,127,127,0.75); } .smactive { background-color: rgba(0,0,127,0.60); } Load your page and enjoy!
  12. MySQL (InnoDB) only very recently got the ability to allow index searches with bitwise operations. With the current (5.7.8) release, you can add a generated or virtual column to the pages table and index that. If the column operation in the query matches the column definition, the index is used. This should look something like the following (untested): ALTER TABLE pages ADD stpublished INT AS (status & 2048) STORED; CREATE INDEX idxstpublished ON pages (stpublished); After that, any queries with matching conditions like "pages.status & 2048 = 2048" or "pages.status & 2048 > 0" should hit the index. That's still a bit bleeding edge, but since Oracle officially promotes this feature (it's a must-have for the also advertised JSON column type to be of use), it should be reasonably stable by now. Of course, you have to have a generated column for every comparison you want to speed up, and having one adds another little performance penalty on insert operations.
  13. I need to have a look what can go wrong with changes in template settings, it worked in my (limited) tests. Not sure I want to go into the page/child templates direction though, as the data model is currently tailored to be template-centric. Making both ways efficient would add a whole layer of complexity (n:m relationship).
  14. No, don't do that. Previously published and then un-published pages still retain their timestamp. Always use the appropriate status flags / selector options.
  15. This looks like wd_shared_image is set to hold multiple images, so $p->wd_shared_image stringifies to a list of all of its childrens' image names but only url and path hold a sensible value as $p->wd_shared_image returns a PageImages instance.
  16. The message looks like the "created" column has a wrong default value, so the create statement for the published column probably triggered the error but isn't its cause. Open the schema for the pages table in phpMyAdmin and have a look there. The default value for "created" should be a date in 'YYYY-MM-DD HH:MM:SS' notation, if it's not, enter something halfway reasonable there (it shouldn't really matter which date though as PW will overwrite it), then try to execute the statements from SystemUpdate12.php again.
  17. $largePargeArray->removeItems($subsetPageArray); should work as PageArray inherits from WireArray.
  18. (Untested) It should be sufficient to assign the correct value for parent (the User class inherits from Page) and pass the correct template in the constructor. $u = new User($templates->get('my-user-parent')); // pass the Template object $u->parent = 222; // you can also pass a Page object or selector string here // continue as usual...
  19. There was a silly mistake in the module config, but that should be fixed in the latest version on github. Currently, the only way to get the template selectable once parent restrictions are in place is to add a valid parent to the settings. Can you describe a little more what kind of logic you have in mind?
  20. @Ivan: A good idea. In fact, the one I initially had in mind, but I somehow got it into my head to save the settings directly with the template configuration which I couldn't. Of course, one thing doesn't necessitate the other and I can both hook into ProcessTemplate and use my own database table. So, version 0.0.6 is on GitHub and does allow that.
  21. A feature request here in the forums prompted me to shape a piece of code I had been tinkering with into a usable module. Template Parents What it does: The list of possible templates for new pages in ProcessWire is purely based on other templates in parent/child relationships managed in the involved templates' family settings. This is most often okay, but sometimes you want to limit creation of pages with a certain templates to individual spots in the page tree, and there's no clear parent/child relationship to go with. The initially quick solution would be to duplicate parent templates for the different spots, but then any change on one of these templates has to be made to the others too, which gets tedious and error prone. Template Parents adds an entry in the Setup menu where you can assign allowed parent pages to templates. These rules are enforced after the regular family settings have been executed, so it builds upon instead of replacing PW's built-in mechanism. There's also an option in ProcessTemplateParents' to enable inheritance, then entries in the Template Parents assignment are inherited down the page tree and also grant template permissions to children, grandchildren and so on. The module can be downloaded from the GitHub repository. It has been tested with PW 2.7 and 3.0.
  22. Haven't tested it in 3.x yet, but I'm about to. Update: tested with 3.x and worked like a charm.
  23. You mean something like this?
  24. Have you tried disabling ACF in the field's settings? If disabling ACF makes it work, you'll probably have to add rules for the elements and classes in your custom styles in the Extra Allowed Content field.
  25. DaveP, is user_agent set in your php.ini? Github's api rejects requests that don't have a user-agent header.
×
×
  • Create New...