Jump to content


  • Content Count

  • Joined

  • Last visited

Community Reputation

71 Excellent

About ethanbeyer

  • Rank
    Sr. Member

Recent Profile Visitors

875 profile views
  1. Thanks again for the responses, @Wanze, @wbmnfktr, @Autofahrn, and @LostKobrakai. All of your answers (again) help me make sense of things I didn't know or understand as fully as I thought I did. I've thought for a long time that the .htaccess file that ProcessWire uses was way more robust (read: better) than other CMS' that don't hide most of the app outside of webroot, but I hadn't thought about necessity of most of it. I think all of my thoughts/worries have been sufficiently addressed.
  2. Sorry to be the guy that comes back like, "wait a minute!"–but I'm still thinking about this. Originally, I was asking, "does ProcessWire need .htaccess, and if so, why?" All the answers given boil down to yes, PHP CMS' need an .htaccess file, and the reasons are speed, security, and delegating to the HTTP server what the HTTP server does best. I hear you all! Thank you again for those replies. Now I want to ask...is the ProcessWire .htaccess file doing too much? Here it is, with comments stripped: Options -Indexes Options +FollowSymLinks # Options +SymLinksifOwnerMatch ErrorDocument 404 /index.php <Files favicon.ico> ErrorDocument 404 "The requested file favicon.ico was not found. </Files> <Files robots.txt> ErrorDocument 404 "The requested file robots.txt was not found. </Files> <IfModule mod_headers.c> Header always append X-Frame-Options SAMEORIGIN Header set X-XSS-Protection "1; mode=block" # Header set X-Content-Type-Options "nosniff" </IfModule> <FilesMatch "\.(inc|info|info\.json|module|sh|sql)$|^\..*$|composer\.(json|lock)$"> <IfModule mod_authz_core.c> Require all denied </IfModule> <IfModule !mod_authz_core.c> Order allow,deny </IfModule> </FilesMatch> <IfModule mod_php5.c> php_flag magic_quotes_gpc off php_flag magic_quotes_sybase off php_flag register_globals off </IfModule> DirectoryIndex index.php index.html index.htm <IfModule mod_rewrite.c> RewriteEngine On AddDefaultCharset UTF-8 # RewriteCond %{HTTPS} off # RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] # RewriteCond %{HTTP:X-Forwarded-Proto} =http # RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] <IfModule mod_env.c> SetEnv HTTP_MOD_REWRITE On </IfModule> # RewriteBase / # RewriteBase /pw/ # RewriteBase /~user/ RewriteRule "(^|/)\.(?!well-known)" - [F] # RewriteCond %{HTTP_HOST} !^www\. [NC] # RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301] # RewriteCond %{REQUEST_URI} "[^-_.a-zA-Z0-9/~]" # RewriteCond %{REQUEST_FILENAME} !-f # RewriteCond %{REQUEST_FILENAME} !-d # RewriteRule ^(.*)$ index.php?it=/http404/ [L,QSA] RewriteCond %{REQUEST_URI} !(^|/)site-[^/]+/install/[^/]+\.(jpg|jpeg|png|gif)$ RewriteCond %{REQUEST_URI} (^|/)\.htaccess$ [NC,OR] RewriteCond %{REQUEST_URI} (^|/)(site|site-[^/]+)/assets/(cache|logs|backups|sessions|config|install|tmp)($|/.*$) [OR] RewriteCond %{REQUEST_URI} (^|/)(site|site-[^/]+)/install($|/.*$) [OR] RewriteCond %{REQUEST_URI} (^|/)(site|site-[^/]+)/assets.*/-.+/.* [OR] RewriteCond %{REQUEST_URI} (^|/)(wire|site|site-[^/]+)/(config|index\.config|config-dev|env)\.php$ [OR] RewriteCond %{REQUEST_URI} (^|/)(wire|site|site-[^/]+)/templates-admin($|/|/.*\.(php|html?|tpl|inc))$ [OR] RewriteCond %{REQUEST_URI} (^|/)(site|site-[^/]+)/templates($|/|/.*\.(php|html?|tpl|inc))$ [OR] RewriteCond %{REQUEST_URI} (^|/)(site|site-[^/]+)/assets($|/|/.*\.php)$ [OR] RewriteCond %{REQUEST_URI} (^|/)wire/(core|modules)/.*\.(php|inc|tpl|module|info\.json)$ [OR] RewriteCond %{REQUEST_URI} (^|/)(site|site-[^/]+)/modules/.*\.(php|inc|tpl|module|info\.json)$ [OR] RewriteCond %{REQUEST_URI} (^|/)(COPYRIGHT|INSTALL|README|htaccess)\.(txt|md|textile)$ [OR] RewriteCond %{REQUEST_URI} (^|/)site-default/ RewriteRule ^.*$ - [F,L] RewriteCond %{REQUEST_URI} "^/~?[-_.a-zA-Z0-9/]*$" # RewriteCond %{REQUEST_URI} "^/~?[-_./a-zA-Z0-9æåäßöüđжхцчшщюяàáâèéëêěìíïîõòóôøùúûůñçčćďĺľńňŕřšťýžабвгдеёзийклмнопрстуфыэęąśłżź]*$" RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !(favicon\.ico|robots\.txt) # RewriteCond %{REQUEST_FILENAME} !\.(jpg|jpeg|gif|png|ico)$ [NC] # RewriteCond %{REQUEST_FILENAME} !(^|/)site/assets/ RewriteRule ^(.*)$ index.php?it=$1 [L,QSA] # RewriteRule ^(.*)$ /index.php?it=$1 [L,QSA] </IfModule> That's 86 lines. For comparison, here's Laravel's: <IfModule mod_rewrite.c> <IfModule mod_negotiation.c> Options -MultiViews -Indexes </IfModule> RewriteEngine On # Handle Authorization Header RewriteCond %{HTTP:Authorization} . RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] # Redirect Trailing Slashes If Not A Folder... RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} (.+)/$ RewriteRule ^ %1 [L,R=301] # Handle Front Controller... RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L] </IfModule> And Wordpress': <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule> I am wondering if the .htaccess has to do as much as it's doing right now, or is some of this stuff redundant to validation already in Core? I fully agree we need it, but I wonder if we could move some of the common configurations out of it, because at the end of the day, the app should be able to work out of the box on either Apache or NGINX with limited knowledge of either system and not need gobs of HTTP configuration. I don't personally know how to do spearhead this effort, but other systems have found a way to do so, and I think ProcessWire could garner more market share if the initial configuration appeared hella simple. The .htaccess (and by extension, conversion to NGINX) scares some people. I think it would be worthwhile to discuss the possibility and plausibility of moving some of those .htaccess configs to the core in some form or fashion.
  3. Thank you all for your answers! It was very exploratory because this is a blind spot for me. I haven't known exactly how this worked, and after all of the explanations, I think I understand a little more fully. Thanks!
  4. Yeah, I don't know the "better way" either, at least in terms of actual methodology - I suppose what I was wondering is if anyone had experience in this realm and could help the ProcessWire community at large detach ProcessWire from viewing Apache as a necessity out of the box. Does that make sense?
  5. I've introduced ProcessWire (gleefully) to quite a few devs I know. One, who is quite a bit more experienced than I am, raised a question that I couldn't answer: Does ProcessWire rely on .htaccess *too much*? I realize that .htaccess handles a lot of baseline security and routing issues within the ProcessWire ecosystem. Inevitably, this leads to a large reliance on Apache, unless one is willing to try to convert those rules to NGINX configurations. This has led me to wonder, is there a better way (PHP based?) of handling routing and security than .htaccess?
  6. Thank you all for your input! This is really helpful, and how I had started seeing the issue as well. What I meant by "attention" was the development maintenance, but you're right: updates don't equate to usefulness. I'm with you - it's what I have used most, also, and for me and the sites I'm building with ProcessWire, I think it makes sense to use one method instead of both. I particularly like using the namespaces in the WireCache as @Zeka mentioned as well - it makes expiring similar things, or preloading similar things, very easy.
  7. Hello, I'm hoping for a little help understanding the different types of caching baked in to ProcessWire, as well as when one should use which. As I understand it, there are two methods for caching, with several different interfaces: 1. Database Caching Within the realm of Database Caching, there is the WireCache class, accessible through the $cache variable. This has various methods, but you can save just about anything to the caches table in the ProcessWire Database, and set a time for expiration, and retrieve it. Nice! It seems like this is the most feature-rich way to cache something that isn't a template, but I don't know how it works performance-wise against, say, MarkupCache. 2. File Caching Then there's File Caching - and the two interfaces that I know of that use this method are Template Caching and the MarkupCache plugin. Template Caching generates the full $page->render(), whereas MarkupCache takes whatever markup one wants to save and outputs that to a file that expires with the given time. Questions and Considerations If saving Markup, which is faster: Database or File Caching? Should we use MarkupCache at all, when WireCache seems to get more attention?
  8. Sorry for the late reply - thank you! That had been confusing me a lot.
  9. I've been looking for the answer for this everywhere - and I appreciate the answer. But *where* in the Core is the "textformatters" attribute instantiated?! I can't find it anywhere. I don't see it in the Textformatter class, or Field, Fieldtype or FieldtypeText. Any ideas?
  10. @Jon this sounds a little strange. Reading most of your comment, I would think that this might have something to do with your Office365 having sending limits that you're going over. The TLS issue is what makes it weird, though - because if it was a limits problem, that would not be happening. Is there anything in the logs that gives what error is encountered, rather than saying it just stops sending?
  11. At the risk of sounding very pedantic, this condition would result in the timestamp for any page with template cache enabled, which is not what I'm looking for. I only want the timestamp to appear on cached versions of the page - so if I am logged in, and am served a page that doesn't give cached pages to logged-in users, I don't want the timestamp (or maybe I would have a different comment that said this page was generated now and is not cached, etc). On the other hand, if I was not logged in, and looked at the source for the same page and was served the Cached version, I'd expect to see the timestamp. Essentially, I am looking to inject the comment ONLY at the time of the creation of the cached page, not on normal render - so this makes me wonder if there's a hook I could grab before page render to determine whether or not the page render was being performed in order to create a CacheFile. Does this make sense?
  12. Well, I feel a bit silly. I didn't think that needed to be done because of the call to $sanitizer->selectorValue($input->get('s')); . Anyhow, you solved my problem - and I think you're right: String Selectors are probably an easier method to go with than Array Selectors until they've been documented better.
  13. In theory, yes - but the largest problem with that approach is that the timestamp is always there. This is mostly for my OCD brain, but I essentially wanted a sanity check in the source that would quickly show that a page was or was not cached, and when.
  14. As a follow-up...has anyone ever built a site using delayed output with template caching? This is a new frontier for me and I don't know how to set it up.
  15. Not sure if this is possible - but I'd like to add something like this to cached pages via Template Cache: <!-- Page Cache Generated 2018-05-22 @ 12:45:44 UTC / Expires 2018-05-29 @ 12:45:44 --> I thought there might be a way to see if a cache file existed for the page in question, and if it did not, to include that comment in the render->cacheFile->save(). Does anyone know?
  • Create New...