Leaderboard
Popular Content
Showing content with the highest reputation on 04/04/2014 in all areas
-
count(array_diff($array_1->explode('id'), $array_2->explode('id')))4 points
-
3 points
-
3 points
-
// could be this. if(count(array_diff($array_1, $array_2)) === 0)) { echo "identical" } Others will come up with other clever ideas I think It don't need to sort(), edited the post don't take this as an example,3 points
-
Hi Sevarf2, Here are my notes to the two files that were patched. The PagefilesManager::url() method is hookable so theoretically there is no patch needed. But since I needed to hack that file anyway, I did not use a hook. Just ask here if you have any questions. I think it would be nice if the developer could define a specific strategy for saving the files (with Hooks). I will open an Issue on GitHub and provide a proposal to ryan. Edit: I do not use pagefileSecure feature, and actually have no idea if it would work with those "hacks" Patches: /wire/core/functions.php function wireMkdir($path, $recursive = false) { //if(!is_dir($path)) return false; $chmodDir = wire('config')->chmodDir; if ($recursive && $chmodDir) { return @mkdir($path, octdec($chmodDir), true); } if(!@mkdir($path)) return false; if($chmodDir) chmod($path, octdec($chmodDir)); return true; } /wire/core/PagefilesManager.php static public function makeCustomPath(Page $page) { // Make subfolders per ID - always two digits (or one per folder) // Example: ID=1780, path = /site/assets/files/17/80/ // ID=19814, path = /site/assets/files/19/81/4/ // ID=205478, path = /site/assets/files/20/54/78/ $tmpPath = ''; $digits = str_split("{$page->id}"); foreach ($digits as $k => $digit) { $tmpPath .= $digit; if (($k+1) % 2 == 0) $tmpPath .= '/'; } if (substr($tmpPath, -1) != '/') $tmpPath .= '/'; return $tmpPath; } === protected function _createPath($path) { if(is_dir($path)) return true; return wireMkdir($path, true); } === static public function _path(Page $page) { $config = wire('config'); $path = $config->paths->files; //$publicPath = $path . ((int) $page->id) . '/'; $tmpPath = self::makeCustomPath($page); $publicPath = $path . $tmpPath; $securePrefix = $config->pagefileSecurePathPrefix; if(!strlen($securePrefix)) $securePrefix = self::defaultSecurePathPrefix; // securePath has the page ID preceded with a prefix which PW's htaccess blocks http requests to //$securePath = $path . $securePrefix . ((int) $page->id) . '/'; $securePath = $path . $securePrefix . $tmpPath; // we track this just in case the prefix was newly added to config.php, this prevents // losing track of the original directories //$securePath2 = $path . self::defaultSecurePathPrefix . ((int) $page->id) . '/'; $securePath2 = $path . self::defaultSecurePathPrefix . $tmpPath; [.. continue method...] } === public function ___url() { return $this->config->urls->files . self::makeCustomPath($this->page); }3 points
-
Have you checked my solution? It works. I have a site with > 200.000 pages each containing images and files. One big disadvantage is that I needed to hack two core files. I'll open a GitHub issue with a proposal how this could be implemented with hooks. If you take a solution like mine, you'd need to write a script which creates the subfolders and moves the files for your existing site. So for example: files/1603/image.jpg must be translated to: files/16/03/image.jpg3 points
-
Sorry, me again. This works too and may best option with page arrays where you have an id. if("{$a1->sort('id')}" == "{$a2->sort('id')}") echo "identical"; Sort them by id first and put into quotes to make them both a string, if string is same they were identical. To go further, you could extend the PageArray with a new method. This can be done with a simple hook. For example in your templates init: wire()->addHook("PageArray::compare", null, function($event){ $a1 = $event->object; $a2 = $event->arguments(0); $event->return = "{$a1->sort('id')}" == "{$a2->sort('id')}"; }); Then you can use it everywhere in your templates like this if($a1->compare($a2)) echo "identical"; If you the hook to an autoload module like the HelloWorld.module you could use this method throughout PW.2 points
-
Works too (with WireArray/PageArray) the trick is to add the two arrays together, PW will remove dublicates. So you can compare count after "merging", if result is different they're not identical. $orig = clone($a1); if($a1->add($a2)->count == $orig->count) $is = "identical"; Edit: hmm, too soon. small correction, needs a clone to keep original array in memory2 points
-
2 points
-
@Wanze I quite like the idea of having a hookable method that would allow consistent path manipulation. If it could rewrite the entire path for a resource then perhaps it could even be used to support things like image delivery from a dedicated sub-domain etc. Edit: Looks like Teppo & Ryan had a similar idea over here.2 points
-
First idea = great Second = already there, right click On mobile here, will come back on the topic!2 points
-
Amazon have their own S3 PHP SDK - https://github.com/aws/aws-sdk-php/tree/master/src/Aws/S32 points
-
Yes, a solution like this will surely be helpful for sites with large data or sites that are hosted on a distributed server architecture. If anyone is interested in developing a FieldType/Module for this, please let me know either via PM or by replying to this thread: https://processwire.com/talk/topic/6036-custom-fieldtype-for-amazon-s3/ and i'll be happily willing to sponsor it!2 points
-
I find hanging them from the ceiling and seeing which one gets closest to the floor works...2 points
-
Currently working on a big project where there will be a lot of user content (photo's). As soon as i finished the modifcation of the Frontend User Profiles module with build-in friends system, that is something i too have to figure out. Instead of Amazone S3 i was looking in to Google Cloud Storage. One reason is they just lowered their prices and i personly like their API. Been playing around with their YouTube v2 API before and since a while with the YouTube v3 API. But also their FreeBase API. MODx Revolution has a nice solution for this where you can setup data providers. Like the default "localhost" there is one for S3 storage too. I'm hoping ProcessWire will have such a solution someday too where you can install data providers (S3, Google Cloud, other CDN) and choose where certain data is going to be stored. Specialy with huge sites having the choice for something else then localhost to store the data. CDN or Cloud Storage have nicer pricing then regular hosting providers when it comes to storage huge amounts of data. One of our other big website (which still runs on MODx) has abot 40 GB of image data. The plan is to migrate this website some day to ProcessWire too. So for this a 'special' fieldtype might solve it for storing images, instead having the ability at core level would be a dream come true2 points
-
You are looking for: foreach ($settings->music as $piece) { echo "<audio src='$piece->song->url'></audio>"; } There is no "path" for a single file - take a look in the cheatsheet.2 points
-
Do you have PW installed in a subdirectory of your html/www root? If so, then /site etc won't work either. You really should be using: <link rel="stylesheet" href="<?php echo $config->urls->templates?>/styles/site.css"> like Martijn suggested.2 points
-
2 points
-
Here are my first couple of sites using PW, critique appreciated! Artists agency Photographer Thanks!2 points
-
Now that, I could not tell you - I have no access to form builder code and have never seen the module outside of the video demo. It would make sense to include a file with this sort of thing wrapped into a function/hook so as to keep the code you're adding separate from the module, for updating/upgrading purposes. Can't sleep... Assuming you would like to add it as a hooked method you could do something simple like: // Attach the hook in the FormBuilder Class $this->pages->addHookAfter('save', $this, 'hookAfterPageSave'); //Define what you want to do after the page is saved function hookAfterPageSave($event) { // argument(0) is the current page on the save $event $anEditablePage = $event->arguments(0); // add the page to editable_pages field (if in FormBuilder Class) $this->user->editable_pages->add($anEditablePage); } This would do essentially the same thing but the FormBuilder class, (or whatever it may be called), would run this method on page save. Look here: http://processwire.com/api/hooks/ for details on how hooks work. Again, the code is coming out of my 3am brain: so no warranty that any of it works.2 points
-
Great to hear you're making progress. The Page Edit Per User adds a new field to every users' page; it's name is editable_pages. This is a Page Field and behaves like any other so to add a value to it when the user creates a page with the form-builder you could do something like: // Get user that made the page $owner = $page->createdUser; // If this is the same user: (Should be on page creation, but anyway) if($user == $owner){ // Turn off outputting formatting for user's page $user->of(false); // Add this current page to the editable_pages field $user->editable_pages->add($page); // Don't forget to save the user's page $user->save(); // Turn output formatting back on $user->of(true); } Just remember that the page created by the using the form builder must have been saved before you can add it to the user's editable_pages field. For clarity purposes: Users in PW are Pages. So accessing the user's fields would be like any other page's field. I haven't used the module but I'm pretty sure you could dynamically add pages to this field with the API as shown in the pseudo-code. Keep at it, you'll get it. BTW: I saw this in the Modules Section: http://modules.processwire.com/modules/schedule-pages/ and thought you might be interested in checking it out, does pretty much what I was demonstrating a couple of posts up.2 points
-
@ryan, It would be nice that it also inherits the data from the fieldgroups_fields.data if that is posible It just looks better2 points
-
I did it again http://soma.urlich.ch/posts/custom-js-in-processwire-admin/1 point
-
Just wanted to post it here for others that might look for an example. I'm currently working on importing a Site to PW2.1. Following code I figured is needed to create pages using the Bootstraped API: <?php include(./index.php) // bootstrap PW $p = new Page(); // create new page object $p->template = 'page'; // set template $p->parent = wire('pages')->get('/about/'); // set the parent $p->name = 'mynewpage_url'; // give it a name used in the url for the page $p->title = 'My New Page'; // set page title (not neccessary but recommended) // added by Ryan: save page in preparation for adding files (#1) $p->save(); // populate fields $p->image = 'path/to/image.jpg'; // populate a single image field (#2) $p->images->add('path/to/image1.jpg'); // add multiple to images field $p->save(); // testing echo 'id: '.$p->id.'<br/>'; echo 'path: '.$p->path; Note: in PW 3 with multi-instance support adding new Objects https://processwire.com/blog/posts/processwire-2.6.21-upgrades-comments-more-on-pw-3.x/#more-updates-on-processwire-3.0 [Edit by Ryan #1] Added first $p->save(); [Edit by Ryan #2] Changed $p->image('...') to $p->image = '...';1 point
-
Hi, Would anyone be interested in creating a custom fieldtype where images are uploaded to an Amazon S3 bucket instead of the /site/assets/ folder? Thanks1 point
-
Please use Matrix Fieldtype & Inputfield Or the ProFields. FieldtypeJson (module) Álpha I've been busy last 2 weeks with a new fieldtype. I needed a fieldtype that generates JSON strings from CSV (excel data). I needed a way to handle a variable amount of columns & needed a way to manage that data. Wanze & Kongondo already worked on a excel crud module with the excellent Excel-like data grid editor Handsontable and I loved that piece of software. Thank you guys. Handsontable is used in the Inputfield part. What the Inputfield does does: If there's no data in the field, the Inputfield shows you a textarea. You could copy 'n past in CSV text in that field. When you save the field, all data is processed. Processing means: Slice till an x amount of data rows. If minimum amount of columns is not reached, pad the columns till the amount you've specified in the settings If the data contains to much columns, slice the redundant amount of columns. Every data left, is trimmed and sanitized Every numbered string will be converted to integers Saved in 2 formats: 1) json and 2) cvs Server side there's a lot of processing needed to perform all this, that is the reason to set a low amount of data rows. On The Inputfield side, the JSON is generated by Handsontable. So this feels a bit dirty. (Server side it does do all the steps in the above list.) For now it's called FieldtypeJson, but i'm not to keen on this name. Output How to output in your template: $page->fieldname // (string) the table markup $page->fieldname->json // (string) JSON string $page->fieldname->csv // (string) CSV string $page->fieldname->rows // (int) number of rows, not really usefull, but needed internally $page->fieldname->columns // (int) number of columns, not really usefull, but needed internally When to use: If you need a small set tabular json data, and you don't know how many columns it has. If you want to have render tables quicky in your site. When not to use: Store very large sets of query -able data. If you have to rely rely on the data. ( all json is stored in a subfield, and the same for csv ) API Side (JSON): // Json string $json = '[["First Name","Last Name","Company Name","Address","City","State","Post","Phone","Email"],["Rebbecca","Didio","Brandt, Jonathan F Esq","171 E 24th St","Leith","TA","7315","03-8174-9123","rebbecca.didio@didio.com.au"],["Stevie","Hallo","Landrum Temporary Services","22222 Acoma St","Proston","QL","4613","07-9997-3366","stevie.hallo@hotmail.com"],["Mariko","Stayer","Inabinet, Macre Esq","534 Schoenborn St #51","Hamel","WA","6215","08-5558-9019","mariko_stayer@hotmail.com"]]'; $page->of(false); // Turn OutputFormatting of $page->fieldname->json = $json; $page->save(); $page->of(true); API Side (CSV): // CSV string $csv = '"First Name","Last Name","Company Name",Address,City,State,Post,Phone,Email Rebbecca,Didio,"Brandt, Jonathan F Esq","171 E 24th St",Leith,TA,7315,03-8174-9123,rebbecca.didio@didio.com.au Stevie,Hallo,"Landrum Temporary Services","22222 Acoma St",Proston,QL,4613,07-9997-3366,stevie.hallo@hotmail.com Mariko,Stayer,"Inabinet, Macre Esq","534 Schoenborn St #51",Hamel,WA,6215,08-5558-9019,mariko_stayer@hotmail.com'; $page->of(false); // Turn OutputFormatting of $page->fieldname->csv = $csv; $page->save(); $page->of(true); After save, all other subfield are updated. So saving JSON will update CSV and the rows and the columns. And saving CSV will update JSON and the rows and the columns. Saving direct to the fieldname, or saving to both json and csv or saving to the rows & columns wil thow a wireException(). Download: source on github Warning: This Fieldtype is Álpha, don't use it in live projects empty field: paste data: imported data: manage data: settings:1 point
-
(Thought I should put a direct link to this on this forum - somehow I forgot to!) This tutorial is aimed at anyone starting out with ProcessWire (whatever their level of expertise) who wants to get a good but basic understanding of how the system works.. It goes back to the beginning and looks at creating fields, template files, templates and then demonstrates how those elements are put together very simply with very ordinary HTML/CSS and a few very simple bits of PHP. This is not a definitive way of creating a site (ProcessWire has no set methods and allows you to work they way you wish), but it should answer some basic questions and get you going. http://wiki.processwire.com/index.php/Basic_Website_Tutorial Note: This tutorial also forms the basis of other tutorials such as the Simple News System and Simple Gallery System.1 point
-
I wish you could extend me - might be preferable to a clone (that would just be scary). Too much work, not enough sleep, don't know what task to tackle next.1 point
-
You can limit amount of columns and rows in the settings. Handson doesn't let you insert or delete more, and if impotered from csv / json, php cut them off. It's in the fields settings. ( while thinking of it, it might be possible that that is not yet on github, but it's already here on the local install ) Great you're thinking about features. Do you mean: Specify real headers in the config, they gonna be used above the dataset. (not part of the actual dataset) Plus an option to disable add/remove columns at all, so data stays in the right columns ? This all to `force` the client to insert the right data ? if you have better/more ideas, please shout.1 point
-
I meant to restrict those possibilities (e.g. as checkbox). If the client should not add new columns, then the item in the context menu in Handsontable should not be active or visible at all. Sorry was not that clear1 point
-
Idea for features Define columns already in the config. The module then displays the handsontable-grid but without data. This way, I can control the data which is entered more precisely. Maybe add some more options like:Enable creation of additional columns Enable to insert additional rows ... These two settings would be very useful for situations where you already know the schema of the data and want to restrict the client from messing up things. Great module anyway, I just thought to write it down before I forget Cheers!1 point
-
1 point
-
Thanks guys! Here are some things that I found already: https://www.foundapp.com/ (wow! looks for files in the disk, gmail, evernote, dropbox, just name it...) http://evernote.com/skitch/ http://www.clipmenu.com/ (seems to be better than jumpcut) https://skyfonts.com/ http://lifehacker.com/182657/how-to-turn-mac-os-x-dashboard-off (great!! ) https://onedrive.live.com/about/en-us/download/ (srsly, the only from the "big ones" that lets you choose the folders to sync) http://wakaba.c3.cx/s/apps/unarchiver http://kapeli.com/dash (lots of documentation for languages) http://koala-app.com/ ( gui compiler for preprocessing languages) http://www.allvu.com/index.php/products/startninja.html (very important!!) http://gimp.lisanet.de/Website/Download.html (try to make "color to alpha" in photoshop ) http://www.ampps.com/ http://www.vagrantup.com/ Ok, enough! By the way, Atom is looking pretty nice1 point
-
Hi, I think it would be really helpful to have an alternative to the default filesystem for large sites or sites that are hosted on distributed servers where the files can be saved externally to the likes of Amazon S3 instead of the '/assets/files/' folder, especially considering that filesystem on servers have a limit of either 32k or 64k for folders/sub-folders. This can be possibly achieved by creating a custom FieldType or a Module that can hook into the fileupload process, but having this built into the core would be a dream!1 point
-
sort($array_1); sort($array_2); $same_array = ($array_1 == $array_2) ? true : false;1 point
-
Actually, it seems Joe was the last poster (13 November 2013) in that thread Wanze points to1 point
-
site/templates/styles/site.css <-- thats relative, you forget the starting / So if your url is http://my-domain.com/products/, the browser is gonna look for /products/site/templates/styles/site.css This should work: ( see the starting slash ? ) <link rel="stylesheet" href="/site/templates/styles/site.css" />1 point
-
To expand a little on marcus post. the templates folder, usually /site/templates/ (if PW is installed in the root) | +----------------+------------------+ | | <link rel="stylesheet" href="<?php echo $config->urls->templates?>dist/css/main.css"> | | | +-+--+-+-+ / \ / custom folder / named css custom folder named dist had 1 slash to much.. changed1 point
-
When including your css and js, do you use something like... <link rel="stylesheet" href="<?php echo $config->urls->templates?>/dist/css/main.css"> ...or are you traversing folders like href="../../css/main.css" ?1 point
-
1 point
-
$page: current page function trunc($string, $length) { return substr($string, 0, strpos(wordwrap($string, $length), "\n")); } echo trunc($page->body, 100); // string 100 characters or little less, body field from the current page, cut-of on word This happens all the time, not problem... echo trunc($child->body, 100); ??1 point
-
It's simple: You have that function function limit_words($string, $word_limit) { $words = explode(" ",$string); return implode(" ",array_splice($words,0,$word_limit)); } A simple call to use this function would be $shorty = limit_words($child->body, 20);1 point
-
Nope, I think we have even more interest than I expected. I try to give date for this soon.1 point
-
Hallo, is that you Raymond? Is it really you?1 point
-
As one of the maintainers of the site I can only agree with everyone here. Thanks Soma, it is really something to be proud of. And thanks to ryan as well for this great system. It is really easy to work with. It makes maintaining a multi language site very easy. I know, what I am talking of …1 point
-
@NooseLadder: this module makes it easy for users to embed maps within content generated with RTE -- TinyMCE, CKEditor etc. Use cases are very different. Just for the record, aforementioned editors do provide a way to edit markup directly, so technically it would also be possible to embed iframes etc. this way. That's something we don't usually want users to do because it often causes more problems than solves. It's better to provide simple solution that outputs consistent markup instead of giving end users too much freedom to do (and break) whatever they want. Added bonus (when compared to embedding iframes directly) is that if you (or Google) ever decide to change how maps should be embedded, you'll only need to change the code once (in the module) instead of changing it everywhere it's been embedded1 point
-
ProcessWire wants to have a local path to save files when you upload them. But using a solution like Teppo's, where you alternate the URL where they live, is certainly a possible way to redirect requests for any file to an alternate location. Another possibility is that I could make PagefilesManager::url() hookable, so that you could modify it with a hook. This would probably be the cleanest method, and I'll be happy to add the hook if anyone wants it. However, you would still need to be responsible for making sure that the files that live in /site/assets/files/* manage to find a way to their new URL location, whether it's literally having them copy to that location, or it's a directory mapped to another drive or server, etc.1 point
-
@Gabi: this sounded like an interesting idea, so I mocked up a proof-of-concept module (Page Render Relocate Assets) that dynamically alters asset requests to point to another location. This isn't, however, something you should yet consider production-ready. Idea is quite simple: the module just hooks after page render and alters generated markup, converting any requests to /site/assets/ to another URL specified via module settings. Just to be on the safe side this (at the moment) only alters requests that start with a double quote and /site/assets, ie. "... src="/site/assets/..." would get replaced, while "Look at my /site/assets/!" or "... src="http://example.com/site/assets/..." wouldn't. To test this I created a new subdomain and pointed it to my own sites /site/assets/. According to this blog post this should be enough, and so far things seem to work just fine. You can see it in action here: http://www.flamingruby.com/about/. Note that one of the images on that page is (for some CKEditor-related reason) embedded with full URL and thus doesn't get "relocated", but other one (the bike) should point to static.flamingruby.com instead. .. so to answer to your question here: changing assets location would require a lot of work at the moment, but this way you can serve them without useless cookies etc. as long as that's what you're after. If you're looking to share the load between multiple servers or something like that, this alone won't do the trick (though if combined with some kind of server-side replication that would be quite possible too.) I might have to take this module a bit further at some point, I'm kind of starting to like where this is going1 point
-
You may also be able to setup an automatic sort by editing the repeater's template file and setting it under the 'Family' tab. Note that the repeater templates aren't visible in your templates list at first so you'll need to check the box to "show system templates" in the filter menu.1 point
-
Hi vanderbreye, I'd love to see something like this is PW. I've used one or two add-ons for ExpressionEngine that do similar. Are you, by chance, planning any features that allow users to only have access to the files they've uploaded? Regards Marty1 point