Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 02/20/2016 in all areas

  1. This week it's a relatively focused blog post, largely in part to much focus going into the ProDrafts documentation today. Specifically, ProDrafts is now in pre-release! Here is today's post: https://processwire.com/blog/posts/prodrafts-now-available-in-pre-release/
    6 points
  2. After doing some testing it turns out that when a user doesn't have access to edit a field the classed were not added since there is no Inputfield to render. Better solution: wire()->addHookBefore('InputfieldWrapper::render', function($event) { $wrapper = $event->object; foreach ($wrapper->getChildren() as $f) { // Only fieldtypes can have tags && make sure the fieldtype has tags if ($f->hasFieldtype && !empty(wire('fields')->get($f->name)->tags)) { $f->set('wrapClass', "tag-" . wire('fields')->get($f->name)->tags); } } });
    4 points
  3. The simplest way would be locking the AmountDiscounted field in the backend and hook to Pages::saveReady and set the value accordingly on each save.
    3 points
  4. Tracy Debugger for ProcessWire The ultimate “swiss army knife” debugging and development tool for the ProcessWire CMF/CMS Integrates and extends Nette's Tracy debugging tool and adds 35+ custom tools designed for effective ProcessWire debugging and lightning fast development The most comprehensive set of instructions and examples is available at: https://adrianbj.github.io/TracyDebugger Modules Directory: http://modules.processwire.com/modules/tracy-debugger/ Github: https://github.com/adrianbj/TracyDebugger A big thanks to @tpr for introducing me to Tracy and for the idea for this module and for significant feedback, testing, and feature suggestions.
    2 points
  5. So this is basically a recreation of a menu tutorial from W3Bits, tweaked to include the Advanced checkbox hack. Demo. Even the Advanced hack itself was tweaked: apparently this bit is causing issues with Safari, so I removed it: @-webkit-keyframes bugfix { from {padding:0;} to {padding:0;} }I found this particular configuration to work quite nicely. A previous menu I tried had a problem with the menu items staying expanded between media query breakpoints, when resizing the browser. Below is the CSS for the menu. You will notice that it is mobile-first: /* Menu from http://w3bits.com/css-responsive-nav-menu/ */ /* Note: the tutorial code is slightly different from the demo code */ .cf:after { /* micro clearfix */ content: ""; display: table; clear: both; } body { -webkit-animation: bugfix infinite 1s; } #mainMenu { margin-bottom: 2em; } #mainMenu ul { margin: 0; padding: 0; } #mainMenu .main-menu { display: none; } #tm:checked + .main-menu { display: block; } #mainMenu input[type="checkbox"], #mainMenu ul span.drop-icon { display: none; } #mainMenu li, #toggle-menu, #mainMenu .sub-menu { border-style: solid; border-color: rgba(0, 0, 0, .05); } #mainMenu li, #toggle-menu { border-width: 0 0 1px; } #mainMenu .sub-menu { background-color: #444; border-width: 1px 1px 0; margin: 0 1em; } #mainMenu .sub-menu li:last-child { border-width: 0; } #mainMenu li, #toggle-menu, #mainMenu a { position: relative; display: block; color: white; text-shadow: 1px 1px 0 rgba(0, 0, 0, .125); } #mainMenu, #toggle-menu { background-color: #09c; } #toggle-menu, #mainMenu a { padding: 1em 1.5em; } #mainMenu a { transition: all .125s ease-in-out; -webkit-transition: all .125s ease-in-out; } #mainMenu a:hover { background-color: white; color: #09c; } #mainMenu .sub-menu { display: none; } #mainMenu input[type="checkbox"]:checked + .sub-menu { display: block; } #mainMenu .sub-menu a:hover { color: #444; } #toggle-menu .drop-icon, #mainMenu li label.drop-icon { position: absolute; right: 0; top: 0; } #mainMenu label.drop-icon, #toggle-menu span.drop-icon { padding: 1em; font-size: 1em; text-align: center; background-color: rgba(0, 0, 0, .125); text-shadow: 0 0 0 transparent; color: rgba(255, 255, 255, .75); } label { cursor: pointer; user-select: none; } @media only screen and (max-width: 64em) and (min-width: 52.01em) { #mainMenu li { width: 33.333%; } #mainMenu .sub-menu li { width: auto; } } @media only screen and (min-width: 52em) { #mainMenu .main-menu { display: block; } #toggle-menu, #mainMenu label.drop-icon { display: none; } #mainMenu ul span.drop-icon { display: inline-block; } #mainMenu li { float: left; border-width: 0 1px 0 0; } #mainMenu .sub-menu li { float: none; } #mainMenu .sub-menu { border-width: 0; margin: 0; position: absolute; top: 100%; left: 0; width: 12em; z-index: 3000; } #mainMenu .sub-menu, #mainMenu input[type="checkbox"]:checked + .sub-menu { display: none; } #mainMenu .sub-menu li { border-width: 0 0 1px; } #mainMenu .sub-menu .sub-menu { top: 0; left: 100%; } #mainMenu li:hover > input[type="checkbox"] + .sub-menu { display: block; } }Below is the markup outputted using mindplay.dk's method. I found it impossible to output with MarkupSimpleNavigation or MenuBuilder. The homepage is added as the first top-level item. Notice the onclicks that make it work on iOS < 6.0. The clearfix class cf for the top ul is important. Otherwise the element will have no height (got bitten by this..). <nav id="mainMenu"> <label for='tm' id='toggle-menu' onclick>Navigation <span class='drop-icon'>▼</span></label> <input id='tm' type='checkbox'> <ul class='main-menu cf'> <?php /** * Recursive traverse and visit every child in a sub-tree of Pages. * * @param Page $parent root Page from which to traverse * @param callable $enter function to call upon visiting a child Page * @param callable|null $exit function to call after visiting a child Page (and all of it's children) * * From mindplay.dk */ echo '<li><a href="' . $pages->get(1)->url . '">Home</a></li>'; function visit(Page $parent, $enter, $exit=null) { foreach ($parent->children() as $child) { call_user_func($enter, $child); if ($child->numChildren > 0) { visit($child, $enter, $exit); } if ($exit) { call_user_func($exit, $child); } } } visit( $pages->get(1) , function(Page $page) { echo '<li><a href="' . $page->url . '">' . $page->title; if ($page->numChildren > 0) { echo '<span class="drop-icon">▼</span> <label title="Toggle Drop-down" class="drop-icon" for="' . $page->name . '" onclick>▼</label> </a> <input type="checkbox" id="' . $page->name . '"><ul class="sub-menu">'; } else { echo '</a>'; } } , function(Page $page) { if ($page->numChildren > 0) { echo '</ul>'; } echo '</li>'; } ); ?> </ul> </nav>Edit: fixed the end part, thanks er314.
    2 points
  6. Well just start using it and help make it stable by submitting bugs you may find.
    2 points
  7. Ok, it's now live in the modules directory: http://modules.processwire.com/modules/tracy-debugger/ Thanks everyone for the feedback thus far, but please keep it coming - I am sure you will have suggestions on how it can be improved! I would also like to add additional 3rd party panels as requested, so take a look here (https://addons.nette.org/#toc-debug-bar-panels) for some possible things you may be interested in. Keep in mind, that link isn't properly scrolling down, so click on the "DebugBar panels" under Categories on the right.
    2 points
  8. I'm happy, I just bought ProDrafts (Dev) !
    2 points
  9. FieldtypeRuntimeMarkup and InputfieldRuntimeMarkup Modules Directory: http://modules.processwire.com/modules/fieldtype-runtime-markup/ GitHub: https://github.com/kongondo/FieldtypeRuntimeMarkup As of 11 May 2019 ProcessWire versions earlier than 3.x are not supported This module allows for custom markup to be dynamically (PHP) generated and output within a page's edit screen (in Admin). The value for the fieldtype is generated at runtime. No data is saved in the database. The accompanying InputfieldRuntimeMarkup is only used to render/display the markup in the page edit screen. The field's value is accessible from the ProcessWire API in the frontend like any other field, i.e. it has access to $page and $pages. The module was commissioned/sponsored by @Valan. Although there's certainly other ways to achieve what this module does, it offers a dynamic and flexible alternative to generating your own markup in a page's edit screen whilst also allowing access to that markup in the frontend. Thanks Valan! Warning/Consideration Although access to ProcessWire's Fields' admin pages is only available to Superusers, this Fieldtype will evaluate and run the custom PHP Code entered and saved in the field's settings (Details tab). Utmost care should therefore be taken in making sure your code does not perform any CRUD operations!! (unless of course that's intentional) The value for this fieldtype is generated at runtime and thus no data is stored in the database. This means that you cannot directly query a RuntimeMarkup field from $pages->find(). Usage and API Backend Enter your custom PHP snippet in the Details tab of your field (it is RECOMMENDED though that you use wireRenderFile() instead. See example below). Your code can be as simple or as complicated as you want as long as in the end you return a value that is not an array or an object or anything other than a string/integer. FieldtypeRuntimeMarkup has access to $page (the current page being edited/viewed) and $pages. A very simple example. return 'Hello'; Simple example. return $page->title; Simple example with markup. return '<h2>' . $page->title . '</h2>'; Another simple example with markup. $out = '<h1>hello '; $out .= $page->title; $out .= '</h1>'; return $out; A more advanced example. $p = $pages->get('/about-us/')->child('sort=random'); return '<p>' . $p->title . '</p>'; An even more complex example. $str =''; if($page->name == 'about-us') { $p = $page->children->last(); $str = "<h2><a href='{$p->url}'>{$p->title}</a></h2>"; } else { $str = "<h2><a href='{$page->url}'>{$page->title}</a></h2>"; } return $str; Rather than type your code directly in the Details tab of the field, it is highly recommended that you placed all your code in an external file and call that file using the core wireRenderFile() method. Taking this approach means you will be able to edit your code in your favourite text editor. It also means you will be able to type more text without having to scroll. Editing the file is also easier than editing the field. To use this approach, simply do: return wireRenderFile('name-of-file');// file will be in /site/templates/ If using ProcessWire 3.x, you will need to use namespace as follows: return ProcessWire\wireRenderFile('name-of-file'); How to access the value of RuntimeMarkup in the frontend (our field is called 'runtime_markup') Access the field on the current page (just like any other field) echo $page->runtime_markup; Access the field on another page echo $pages->get('/about-us/')->runtime_markup; Screenshots Backend Frontend
    1 point
  10. Docker (http://www.docker.com) is an open platform for building, shipping and running distributed applications. Docker containers are a great way to package a complete application with its specific dependencies in a portable way so that it can easily be deployed on any compatible network or cloud infrastructure. Recently I spent a few days making my ProcessWire site run in a Docker container, and - as I could not find any good tutorial for this - it sounded like a good idea to write one. You will find on the web plenty of presentations and tutorials about Docker, so I won't start with the basic concepts, and this tuto assumes that you have a first understanding of Docker's fundamentals. What we want to do here is to migrate an existing site to a set of docker containers. Therefore, to start with, you should have: - docker installed on your computer; - the site directory of your ProcessWIre site - a backup of your site's MySQL database Let's start. Create a docker container for the site database For several reasons (insulation, security, scalability), it is preferable to host the site database in a separate docker container. 1. Set-up a SQL database with MariaDb or MySQL $ docker run --name database -e MYSQL_ROOT_PASSWORD=rootdbpassword -d mariadb Here I choose to use the MariaDB official container in its latest version, but MySQLwould be just fine as well. 2. Run a PhpMyAdmin container and create the ProcessWire database We first select an simple image with PhpMyAdmin on the Docker Hub: nazarpc/phpmyadmin and we create a docker container based on this image. This container will access the port exposed by the database container via a private networking interface. We specify this with the `--link` option. It can be run temporarily (and exited by ctrl-C): docker run --rm --link database:mysql -p 8881:80 nazarpc/phpmyadmin Or it can be run as a daemon in the background: docker run -d --name phpmyadmin --link database:mysql -p 8881:80 nazarpc/phpmyadmin From phpmyadmin (accessed from your browser at http://hostaddress:8881) you can now create your ProcessWire database, create a dedicated user for it, and import the database content from a previously saved SQL file. Note: alternatively, you can do all database operations from the command line in the database docker container created during step 1, or use another mysql user interface container if you prefer… 3. Update the database parameters in your site configuration In your site's `config.php` file, the sql server name shall be set to `mysql`: $config->dbHost = 'mysql'; Other `$config->dbXxx` settings shall match the database name, user and password of the just-created database. Create a Docker Image for Apache, PHP and the Processwire site 1. Create an image-specific directory with the following contents and `cd` to it bash-3.2$ ls -l . config .: total 16 -rw-rw-rw- 1 jean-luc staff 1163 21 aoû 12:09 Dockerfile drwxr-xr-x 17 jean-luc staff 578 17 aoû 12:48 ProcessWire drwxr-xr-x 7 jean-luc staff 238 21 aoû 12:07 config drwxr-xr-x 7 jean-luc staff 238 20 aoû 18:46 site config: total 160 -rw-rw-rw- 1 jean-luc staff 160 20 aoû 18:28 msmtprc -rw-rw-rw- 1 jean-luc staff 72518 20 aoû 18:56 php.ini where: `ProcessWire` contains the version of ProcessWire that we want to use for this site; It can be retrieved from github with a link like https://github.com/ryancramerdesign/ProcessWire/archive/{version}.zip` For example, the 2.6.13 dev version can be obtained by the link https://github.com/ryancramerdesign/ProcessWire/archive/7d37db8d6b4ca6a132e50aff496a70e48fcd2284.zip `site`: our site-specific files `Dockerfile`: the dockerfile for building the image (see below) `config`: a directory containing specific configuration files copied to the docker image (see below) 2. Set the `Dockerfile` content FROM php:5.6-apache RUN apt-get update \ && apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libmcrypt-dev libpng12-dev zziplib-bin msmtp\ && a2enmod rewrite \ && a2enmod ssl \ && docker-php-ext-install mysqli pdo_mysql iconv mcrypt zip \ && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \ && docker-php-ext-install gd EXPOSE 80 EXPOSE 443 # Add a specific php.ini file COPY config/php.ini /usr/local/etc/php/ # Configure the mail sent utility msmtp (http://msmtp.sourceforge.net) and make it readable only by www-data COPY config/msmtprc /usr/local/etc/php/ RUN chmod 600 /usr/local/etc/php/msmtprc \ && chown www-data:www-data /usr/local/etc/php/msmtprc # Remove all default site files in /var/www/html RUN rm -fR /var/www/html/* # Copy ProcessWire core files COPY ProcessWire/wire /var/www/html/wire COPY ProcessWire/index.php /var/www/html/index.php COPY ProcessWire/htaccess.txt /var/www/html/.htaccess # Copy site-specific files COPY site /var/www/html/site # Make www-data the owner of site-specific files RUN chown -R www-data:www-data /var/www/html/site VOLUME /var/www/html/site Based on the official image `php:5.6-apache`, it installs missing packages to the system, adds mod-rewrite and mod-ssl to Apache, plus a number of PHP modules needed by Processwire (core or modules): mysqli, pdo_mysql, iconv, mcrypt, zip, and gd. Then it copies the site files to the location expected by the Apache server. Finally it declares a Docker volume `/var/www/html/site` (i.e. the site files and assets), so that it can be shared with other containers. 3. Set the msmtp configuration We need to configure a sendmail utility, so that we can send emails from php, for example when a user registers on the website. The simplest way to do it is to rely on an external smtp server to do the actual sending. That's why we use msmtp. - define the desired smtp account in `config/msmtprc` account celedev-webmaster tls on tls_certcheck off auth on host smtp.celedev.com port 587 user webmaster@celedev.com from webmaster@celedev.com password thepasswordofwebmasteratceledevdotcom - in `config/php.ini`, configure the sendmail command so it uses msmtp: sendmail_path = /usr/bin/msmtp -C /usr/local/etc/php/msmtprc --logfile /var/log/msmtp.log -a celedev-webmaster -t 4. Build the Docker image docker build -t php-5.6-pw-celedev . 5. Create a Data-only container for the site files docker run --name celedev-data php-5.6-pw-celedev echo "Celedev site data-only container" 6. Run the web server container docker run --name celedev-site -p 8088:80 --link database:mysql --volumes-from celedev-data -d php-5.6-pw-celedev Note that this container is linked to our database and shares the 'celedev-data' volume created previously During development, it can be convenient to keep an access to the host file system from the container. For this, we can add a shared volume to the previous command: docker run --name celedev-site -p 8088:80 --link database:mysql -v /Users/jean-luc/web/test-docker:/hostdir --volumes-from celedev-data -d php-5.6-pw-celedev Our ProcessWire website is now up and running and we can test it in our browser at http://hostaddress:8088. Great! What we now have in Docker bash-3.2$ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE php-5.6-pw-celedev latest 2aaeb241c2e2 3 hours ago 1.149 GB nazarpc/phpmyadmin latest e25cd4fd48b3 8 days ago 521 MB mariadb latest dd208bafcc33 2 weeks ago 302.2 MB debian latest 9a61b6b1315e 5 weeks ago 125.2 MB bash-3.2$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 68cc5d976f0d php-5.6-pw-celedev "apache2-foreground" 20 hours ago Up 20 hours 443/tcp, 0.0.0.0:8088->80/tcp celedev-site 0729fe6d6752 php-5.6-pw-celedev "echo 'Celedev site d" 20 hours ago Exited (0) 20 hours ago celedev-data e3e9e3a4715c mariadb "/docker-entrypoint.s" 3 days ago Up 3 days 3306/tcp database Saving the site data We can create an archive of the site files by running a tar command in a dedicated container: bash-3.2$ docker run --rm -it --volumes-from celedev-data -v /Users/jean-luc/web/test-docker:/hostdir debian /bin/bash root@2973c5af3eaf:/# cd /var/www/html/ root@2973c5af3eaf:/var/www/html# tar cvf /hostdir/backup.tar site root@2973c5af3eaf:exit bash-3.2$ Tagging and archiving the Docker image We can also add a tag to the docker image that we have created in step 4 (recommended): bash-3.2$ docker tag 2aaeb241c2e2 php-5.6-pw-celedev:0.11 bash-3.2$ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE php-5.6-pw-celedev latest 2aaeb241c2e2 3 hours ago 1.149 GB php-5.6-pw-celedev 0.11 2aaeb241c2e2 3 hours ago 1.149 GB nazarpc/phpmyadmin latest e25cd4fd48b3 8 days ago 521 MB mariadb latest dd208bafcc33 2 weeks ago 302.2 MB And we can archive this image locally if we dont want to push it now to the Docker Hub: bash-3.2$ docker save php-5.6-pw-celedev:0.11 | gzip > php-5.6-pw-celedev-0.11.tar.gz And that's it! You now have a portable image of your ProcessWire website that you can run directly on any docker-compatible system.
    1 point
  11. Hi there, I'm currently starting out with some already quite big projects in cooperation with a partner agency in Munich. There are different scopes of work from rather simple-in-structure content websites to a quite complex SaaS webapp in the pipeline. Therefore I'm looking for possible partnerships with at least one freelancer to assist in these projects, possibly as long-term collaboration. Some proximity to our office in munich would be preferable, but is not required, as is knowledge of the german language. Please drop me a line on the forum if you're interested, so we can get into the details. Greetings, Benjamin
    1 point
  12. http://ukmoths.org.uk Hi, I launched this back in late 2015 but just decided to post it here. It's a complete rebuild in ProcessWire of a site that's been running and growing for at least 15 years in one form or another. The site aims to illustrate all of Britain's moths (not quite there yet!), and despite the obscure subject matter, gets quite a lot of traffic. Hence I've used ProCache to keep things snappy and I'm pleased with the performance. There are over 7000 photos on the site. I should say that the design is not mine, but a purchased template. It took a while to find a template that I thought could portray these under-appreciated creatures in a good light. The most challenging aspects were importing all the data and images from the old system, and getting aspects of the search to work in the way I wanted. The best part is that it's so much easier to add new content! Thanks for ProcessWire, and thanks Ryan and everyone else in the forums! Cheers, Ian.
    1 point
  13. You could use the parallax or maybe the sticky component. I usually solve this by checking scroll amount with jQuery and if that exceeds a given amount (px) I add a class to the nav (or the body), and apply new CSS styles to the nav.
    1 point
  14. Now I got it working ! I check again the username in this case, therefore I grab the username at the beginning of this code. $usernamevalue = $sanitizer->username($input->post->user);//grab the username after submit $database = $this->wire('database'); $name = $usernamevalue; $query = $database->prepare("SELECT attempts FROM session_login_throttle WHERE name=:name"); $query->bindValue(":name", $name); $query->execute(); $numRows = $query->rowCount(); if ($numRows) list($attempts) = $query->fetch(PDO::FETCH_NUM); echo $attempts;//this outputs the login attempts Hope this helps others with the same problem.
    1 point
  15. Thanks for the explanation, now I get it Yes, you are right, I suppose normally I (we) will not need Force Scream at all. I just misunderstood what it is for. I am also quite happy with Strict Mode turned off too.
    1 point
  16. Thanks for that screenshot - that helps! What you are seeing there is because you have Force Scream mode enabled. I assumed you are getting the notice on the entire page blocking the site (like you get in Strict Mode). In reality I don't think you should have Force Scream enabled by default - its only purpose is to show notices/warnings that are suppressed by PHP's @ shutup operator. This can be useful when debugging your code in certain circumstances, but if you are using @ then you are intentionally silencing these errors. I don't think they are typically a good practice, but there can be times when they can be considered acceptable. Anyway, you can disable both Strict and Force Scream modes and you will still get notification of notices and warnings in Tracy. Try these in one of your template files to test: trigger_error("Warning TEST", E_USER_WARNING); trigger_error("Notice TEST", E_USER_NOTICE); With Strict mode ENABLED they will be a full screen error, that you can skip using the "skip error" when you hover over the "Warning Test": But with Strict mode DISABLED, it will be in the Debugger bar: Does that make sense and allow you to work how you want? PS Since I have that screenshot showing the "Skip Error" option, also note the "Search" option which links to a Google search of the issued error - a nice little shortcut
    1 point
  17. @szabesz - sorry about that. I am guessing that you have the Force Scream mode checked? There is what I consider a bug in Tracy: https://forum.nette.org/en/25569-strict-and-scream-modes-together - I don't think that Force Scream should show warnings/notices from the Tracy core. Initially I modified the Tracy core to handle this better, but it turned out not to work in some server configs, so I went back to using the @ to suppress the session_start error. Anyway, I think if you save the config settings page for this module again it should get things working - I now prevent Strict and Force Scream modes from being abled at the same time. Please let me know if that works for you.
    1 point
  18. You can make your own array and pass it as an argument to the render() method. A short snippet exemple for your need : $website = ""; $options = array('headline' => '<h2>Einträge</h2>'); if (strlen($website)<=0) { $temp = array('commentHeader' => 'Geschrieben von {cite} am {created}'); } else { $temp = array('commentHeader' => 'Geschrieben von <a href="{website}">{cite}</a> am {created}'); } $options = array_merge($options, $temp); $temp = array( 'dateFormat' => 'd/m/Y', 'encoding' => 'UTF-8', 'admin' => false ); $options = array_merge($options, $temp); echo $page->guestbook->render($options); // argument as Array()
    1 point
  19. https://github.com/ryancramerdesign/ProcessWire/blob/master/wire/modules/Session/SessionLoginThrottle/SessionLoginThrottle.module#L85-L90
    1 point
  20. 1 point
  21. hi is this the thread you were looking for? https://processwire.com/talk/topic/11577-how-do-you-develop-on-a-live-site/?hl=%2Bdevelop+%2Blive+%2Bsite cheers, Tom
    1 point
  22. cool, glad it's working out; i just added table css, from uikit to the scoped css; not sure how needed it is, but i just started using tables in my documentation and saw there was no styling; ** i'll be adding the table styles to the next update
    1 point
  23. https://github.com/ryancramerdesign/ProcessWire/tree/devns Downgrading to 2.7So long as you haven't modified your template or module files to add PW 3.x specific code to them (like a namespace), you can easily switch between ProcessWire 2.7 and 3.0 simply by swapping the /wire/ directory and /index.php file from the appropriate version. ProcessWire 3.x doesn't make changes to the database, so the database should be identical between 2.7 and 3.0.
    1 point
  24. There are no changes on database level, so you could downgrade as long you don't rely on pw3.0 only modules.
    1 point
  25. No pun intended - but now I wish I had thought of that! Yes, each moth is a page, and in fact each photo is a child of the 'moth' page, so has it's own page too. This is a historical thing - lots of other sites are linking directly to the individual photo pages from the old site, so I made the new site replicate that structure albeit now with friendly urls. It probably would have been a lot simpler to have the photos as a repeater field in the moth template but I needed individual urls for these external links. Thanks Dave. I submitted it but I think it's still working its way through the system.
    1 point
  26. For the redirect maybe read these comments: https://github.com/ryancramerdesign/ProcessWire/issues/1605
    1 point
  27. Heythere, to run the XML sitemap module from pete you'll have to add 3 more lines to your config: location = /sitemap.xml { try_files $uri $uri/ /index.php?it=$uri&$args; } Otherwise you'll get an 404 error. Cheers from austria!
    1 point
  28. Hi adrianmak, here's a good read: https://github.com/ryancramerdesign/ProcessWire/blob/master/wire/modules/Markup/MarkupAdminDataTable/MarkupAdminDataTable.module It's not that don't want to fish and cook for you, but fishing your self will give you more experience.
    1 point
  29. Getting warmer....(OK, so my icons suck, but hey...we're 75% there. ).. Page Edit List View Page Edit Grid View Page Edit Insert Media ProcessMediaManager
    1 point
  30. Seems like I've got the first job thanks to the developer directory
    1 point
  31. As for your wish request. It is already possible to track changes, what -> old -> new value. $user->setTrackChanges(true); wire()->addHookAfter("User::changed", null, function($event){ $what = $event->arguments("what"); $old = $event->arguments("old"); $new = $event->arguments("new"); echo "changed: " . $what . " - " . $old . " -> " . $new; });
    1 point
  32. Changing core modules is never an option. Not even consider it temporarely. But there's plenty of ways and hooks you can change behaviour of core modules. There a couple ways to do that, in templates consider this // current viewed language $viewLang = $user->language; // clear user page cache $pages->uncache($user); // saved user lang echo wire("user")->language; // set back viewed language $user->language = $viewLang; Or there would be a ways to handle it with a simple autoload module. Since the language is set after the init() you can get the stored user language there. Then Language support sets the language on the ready() method, so you could get the currently viewed language in the ready() of your module and compare.
    1 point
  33. I'm not sure I agree that it's a good idea or that it would make more sense to clients. I think what makes the most sense to clients is when structure represents reality, both front-end and back-end. In that context, the homepage is the root page, the common ancestor of all others. The more you abstract those things, the less sense it makes to clients, at least in my experience. As a result, I encourage people to use the homepage as the homepage rather than trying to abstract it to somewhere else. If you are going to abstract it, then it depends how you do it. I would avoid handling it from the htaccess and instead edit your /site/templates/home.php to load and render the other page that you want to represent the homepage. $otherPage = $pages->get('/path/to/your/abstracted/homepage/'); $otherPage->you_be_homepage = true; echo $otherPage->render(); In the page represented by that path above, you'd want to have it throw a 404 (via it's template) when you_be_homepage is not set, just by throwing this at the top. if(!$page->you_be_homepage) throw new Wire404Exception(); or make it redirect to the root page: $session->redirect('/'); Using this strategy, you shouldn't have to consider any effects on SEO as the abstraction will be invisible from the outside.
    1 point
  34. @Nik, you are right of course. Already changed it. @Matthew, seems interesting but I really like to keep it simple and adapted to each situations need. What you are asking can be closely achieved by creating a "dev" folder inside the templates folder and copying there your styles and scripts folders. Then, put this line on the top your header.php: if ($user->name == 'me') $config->urls->templates .= "dev/";
    1 point
  35. This is really interesting stuff and I'm learning so much from it. I've already tested Soma's code and it works very well. Is there a way of configuring $form->render() so that it outputs different html (divs for ul/li etc.)?
    1 point
  36. After Ryan's latest incarnation of Blog Profile I wanted to see if I could learn something from there to my own workflow. It turned out very nicely and this seems like a perfect template approach for me. Wanted to share it with you guys. Folder structure under templates folder: templates/markup/ templates/markup/helpers/ templates/markup/layouts/ templates/scripts/ templates/styles/ And it all begins from here: templates/markup/index.php -this is the "complete" html file, it has doctype, head and starting and ending body. There is very little "logic" here, it's more like a container. There is one very important code snippet there though: <?php if ($page->layout) { include("./markup/layouts/{$page->layout}.php"); } else { include("./markup/layouts/default.php"); } ?> Code above goes between header and footer of your site, that will be the main content. I call it layout, but the better name would be "content layout" or "inner layout" or something like that. Then the templates/markup/layouts/ folder will keep at least default.php file, but probably few others, like "threeColumns.php", "frontpage.php", "gallery.php" etc.. you got the idea. Each of the actual pw template files are then purely "controllers" - no actual markup generated there. All markup are done in files inside templates/markup/ folder and it's subfolders. This is how template file templates/home.php on one site I am building right now looks like: <?php // Carousel items $t = new TemplateFile(wire('config')->paths->templates . 'markup/helpers/carousel.php'); $t->set('carouselPages', $page->carousel); $page->masthead = $t->render(); // Tour themes $t = new TemplateFile(wire('config')->paths->templates . 'markup/helpers/items.php'); $t->set('title', "Get inspired from our <strong>tour themes</strong>"); $t->set('items', $page->featured_themes); $t->set('description', $page->themes_description); $t->set('url', $config->urls->root . "themes/"); $t->set('linkTitle', "All themes"); $page->main .= $t->render(); // National parks $t = new TemplateFile(wire('config')->paths->templates . 'markup/helpers/items.php'); $t->set('title', "Seven beautiful <strong>national parks</strong>"); $t->set('items', $page->featured_parks); $t->set('description', $page->parks_description); $t->set('url', $config->urls->root . "national-parks/"); $t->set('linkTitle', "All national parks"); $page->main .= $t->render(); $page->layout = "frontpage"; include("./markup/index.php"); This uses few "helper" markup files from templates/markup/helpers/ folder (namely carousel.php and items.php). Here is the carousel.php for your reference: <?php /* Generates the markup for the frontpage carousel */ if (count($carouselPages) < 1) return; $styles = ''; echo "<div id='carousel'><ul class='rslides'>"; foreach($carouselPages as $key => $p) { echo "<li class='c-item c-item-$key'>"; echo "<img src='".$p->image->getThumb('carousel') ."' alt='' />"; echo "<p>$p->summary</p>"; echo "<a class='button' href='{$p->link->url}'>$p->headline</a>"; echo "</li>"; } echo "</ul></div>"; Then populates the $page->masthead and $page->main properties and then set's the inner layout to "frontpage". That templates/markup/layouts/frontpage.php file is very simple on this site, but could be much more complicated if needed: <div id="masthead"> <?= $page->masthead; ?> </div> <div id="main" class="wrap"> <?= $page->main; ?> </div> Frontpage is rather unique and I could have done all the markup on the frontpage.php file also. But I do want to re-use those "carousel" and "items" components on other places as well. But if I do have totally unique stuff, where I do want to get "quick and dirty" this approach allows it. Then my template file would be something like this: $page->layout = "campaign2012"; include("./markup/index.php"); And then all the markup would be in that templates/markup/layouts/campaign2012.php Blog profile really gave me a good ideas (cleaner folder structure etc) and using TemplateFile class adds nice possibilities. This is of course just a one way to manage your templates, but hopefully someone of you finds this helpful when thinking about how you like to structure this stuff. PS: If you are just getting started with PW, then I recommend using the head and foot includes method from demo install. There is nothing wrong with that method and only more complicated sites starts to benefit from these methods introduces in this topic.
    1 point
×
×
  • Create New...