-
Posts
2,776 -
Joined
-
Last visited
-
Days Won
40
Everything posted by Macrura
-
@bracketfire - this should work: $facility->region_page = '';
-
Hi - I was able to read id3 tags from audio files very easily using this library and the api, but now i'm stuck trying to get this to work inside a module; in my api test, i just did this: $templates = $config->paths->templates; require_once("{$templates}tools/getid3/getid3.php"); $getID3 = new getID3; $album = $pages->get(2130); foreach($album->children as $track) { $audio = $track->audio_file_p; // Analyze file and store returned data in $track->tags $track->tags = $getID3->analyze($audio->filename); echo $track->tags['tags']['id3v2']['title'][0]; echo $track->tags['tags']['id3v2']['artist'][0]; echo $track->tags['tags']['id3v2']['track_number'][0]; echo $track->tags['audio']['bitrate']; echo $track->tags['playtime_string']; } but now in trying to get this to work inside a module, i can't get the id3 to return the array, not sure what I'm doing wrong... this code is within a method that runs on a saveReady hook: <?php require_once(dirname(__FILE__) . '/getid3.php'); $getID3 = new getID3; $file = $page->audio_files->first(); $tags = $getID3->analyze($file->filename); $title = $tags['tags']['id3v2']['title'][0]; $this->message($title); I did a print_r into a spare field on the $page but it only returned the number 1.. i guess there is something that isn't quite right about the file path or the way the classes are working together? thanks!
-
Repeater field and visibility rule storage problem
Macrura replied to Juergen's topic in General Support
@Juergen - i don't think dependencies can work within repeaters; Have you checked the js console? maybe this helps? -
return field value inside repeater inside TableField
Macrura replied to sakkoulas's topic in General Support
Have you tried echoing the values through the code to make sure that your comparisons will work? <?php foreach ($page->pageTable as $pt) { foreach ($pt->repeater as $rp) { echo $someValue; echo $rp->field1; echo $rp->field2; echo $rp->field3; if( $rp->field1 >= $someValue && $rp->field2 <= $someValue ) { echo $rp->field3; } } } -
@dazzyweb - you're right, maybe the first thing we all need to do with new clients is to have a meeting where we explain these differences; I try and do this whenever possible, and it helps. And it's true what Joss says that most clients are completely in the dark about the world of web design, and the internet in general. This places a larger burden upon us web designers because of the training and support implications, and that's an area that i'm trying to deal with now, like for example marking up budgets to account for all of the question-answer, training sessions, and making docs...
-
The linchpin mentality would be espouse all possible solutions appropriate to the scope of the project, considering all elements including budget, time frame, intended audience type and size, target devices, developer's time resources, with the goal to ship it on time and on budget. Themeforest is a great resource for front end designs, and I use it when appropriate (and also codecanyon). But don't expect to get much in terms of support; also sometimes the technologies used are not quite up to date, and the css can be bloated. We all love bespoke–after all, the engine running the site is already as bespoke as it can get without writing your own CMS. But most clients I work with can't afford bespoke frontend and backend so a choice has to be made. I have a few "go-to" TF authors that are great both in terms of design and code quality. The clients usually pick the template by visiting TF. If this was my full time job, I would probably only do 100% bespoke front end because it would be more fun and engaging. But this is all relative- we're already abstracted a few levels away from the bottom with frameworks, css preprocessors, and CMFs... Nobody Cares How Hard You Worked
-
if you want to go further, you can use the nested accordion which allows for child accordions of the main topic; you would need to create child pages for each main subject; in that case your template might look like this: <?php $docs = $pages->get(4259); ?> <div id="docs"> <ul id="cbp-ntaccordion" class="cbp-ntaccordion"> <?php foreach($docs->children as $doc) { ?> <li> <h3 class="cbp-nttrigger"><?php echo $doc->title ?></h3> <div class="cbp-ntcontent"> <?php echo $doc->body;?> <?php if($doc->children->count()) { ?> <ul class="cbp-ntsubaccordion"> <?php foreach($doc->children as $child) { ?> <li> <h4 class="cbp-nttrigger"><?php echo $child->title?></h4> <div class="cbp-ntcontent"> <?php echo $child->body?> </div> </li> <?php } ?> </ul> <?php } ?> </div> </li> <?php } ?> </ul> </div> <script src="<?php echo $config->urls->templates ?>_admin_custom/js/jquery.cbpNTAccordion.min.js"></script> <script> $( function() { $( '#cbp-ntaccordion' ).cbpNTAccordion(); }); </script> in this code the sub-accordion is shown if there are child pages, and then it outputs the body of each child page in a sub-accordion, and it will end up looking something like this: a more advanced implementation with edit links and an add new doc for superusers: <?php $docs = $pages->get(4259); ?> <div id="docs"> <ul id="cbp-ntaccordion" class="cbp-ntaccordion"> <?php foreach($docs->children as $doc) { ?> <li> <h3 class="cbp-nttrigger"><?php echo $doc->title ?></h3> <div class="cbp-ntcontent"> <?php echo $doc->body;?> <?php if($user->hasRole('superuser')) { ?> <div style="float:right;font-size:11px;"> <a href="<?php echo $config->urls->admin?>page/edit/?id=<?php echo $doc->id?>">Edit: "<?php echo $doc->title?>"</a> </div><?php } ?> <?php if($doc->children->count()) { ?> <ul class="cbp-ntsubaccordion"> <?php foreach($doc->children as $child) { ?> <li> <h4 class="cbp-nttrigger"><?php echo $child->title?></h4> <div class="cbp-ntcontent"> <?php echo $child->body?> <?php if($user->hasRole('superuser')) { ?> <div style="float:right;font-size:11px;"> <a href="<?php echo $config->urls->admin?>page/edit/?id=<?php echo $child->id?>">Edit: "<?php echo $child->title?>"</a> </div><?php } ?> </div> </li> <?php } ?> </ul> <?php } ?> </div> </li> <?php } ?> </ul> <?php if($user->hasRole('superuser')) { ?> <div style="float:right;font-size:13px;"> <a href="<?php echo $config->urls->admin?>page/add/?parent_id=4259"> <button class="ui-button ui-widget ui-corner-all head_button_clone ui-state-default" name="button" value="Add New" type="button"><span class="ui-button-text"><i class="fa fa-plus-circle"></i> Add New Doc</span></button> </a> </div><?php } ?> </div> <script src="<?php echo $config->urls->templates ?>_admin_custom/js/jquery.cbpNTAccordion.min.js"></script> <script> $( function() { $( '#cbp-ntaccordion' ).cbpNTAccordion(); }); </script>
-
yeah but a little api magic can cure that.. open up your tools or api playground and: $pp = $pages->get(1234); // page you're adding the children to the page table foreach($pp->children as $child) { $pp->page_table_field->add($child); }
-
@Lance If I recall correctly, there is a setting for the page table field that will enable it to show items not created by the page table and show the option to add them. You would see that below the page table.
-
This is a very simple way to display some instructions to the admin users. Before starting, you need to write some docs; they can be a hidden branch of your page tree, using basic-page, or a different template of your choosing. You should make each subject it's own page under the docs so you can output each one under an accordion trigger. Required Module: Admin Custom Pages 1.) Follow all instructions to install the module; Also add the ACP_scripts_and_styles field to the admin template. 2.) Make a new page under admin, called Docs or whatever; assign the process as described in the module instructions. 3.) Make a template in your themes directory to generate the output of the docs page. 4.) Select that template from the page select in the admin custom page you created. 5.) also make a folder to keep your admin custom pages scripts and styles; 6.) create a css file to use for the display output and some basic styles (like ol, ul li etc..) 7.) Add the custom css file to your ACP_scripts_and_styles field. You can use any output you want, but i'm using a nested accordion, which is provided here: http://tympanus.net/codrops/2013/03/29/nested-accordion/ this is the content of the admin custom page: <?php $docs = $pages->get(4259); ?> <div id="docs"> <ul id="cbp-ntaccordion" class="cbp-ntaccordion"> <?php foreach($docs->children as $doc) { ?> <li> <h3 class="cbp-nttrigger"><?php echo $doc->title ?></h3> <div class="cbp-ntcontent"> <?php echo $doc->body;?> </div> </li> <?php } ?> </ul> </div> <script src="<?php echo $config->urls->templates ?>_admin_custom/js/jquery.cbpNTAccordion.min.js"></script> <script> $( function() { $( '#cbp-ntaccordion' ).cbpNTAccordion(); } ); </script> you'll also want to add the provided css, js and fonts that come with the Nested Accordion; in the css file you'll need to point the fonts to the actual font directory, for example: /site/templates/_admin_custom/fonts/icomoon_arrows/icomoon.eot it should come out looking something like this: *if you are using Reno theme, you can customize the icon, like for example fa-book, which is used in this example: -- Thanks & Credits to Diogo for originally creating the ACP module, and for Nico for getting it to work with the new admin theme system...
- 11 replies
-
- 18
-
-
@Joss - yes, i'll post the complete instructions as a new thread in tutorials, and link to that here - would that be ok? here's a first draft... https://processwire.com/talk/topic/8392-simple-built-in-docs/?p=81303
-
@Joss - using a super simple implementation now for docs, using admin custom pages and a nested accordion. obviously not as developed as your idea, but took about 20 minutes to setup and now this client can read the docs from their PW admin; screenshot: : *changed to single screenshot
-
cool.. this is all working great... will update my other post with the changes to the required code to output... as far as uses: - use a field for quickly importing child pages using structured data - use for editable settings (site settings, sliders, portfolios, other jquery plugins with a lot of parameters) thanks again for making this!
-
@Lance - I think you'll find that for the most part it is easiest to keep the pagetable pages as children of the page, but it will also depend a lot on your structure, and whether that page has children already, in which case put them somewhere else.. some examples of where i've use pagetables, and i think it will make sense: | Page | PageTable Children | |-----------|--------------------| | Album | Tracks | | Slide | Captions | | Portfolio | Images | | Vignettes | Vignette | i think if you use the reno theme and also lister pro, it actually won't matter that much where you put them; but in a lot of cases having them as children keeps things tidy and you can always get the relation of a pagetable item by calling it's parent. and you can add pages not through the page table, and it will pick them up and ask you if you want to add them. For PDFs, depending on the amount on one page, i might still consider good old repeaters
-
Limit page children to specific template (as page option)
Macrura replied to MarcinP's topic in API & Templates
I usually just need one template called 'option' with a title field and a container called 'option-index', also with only title. That I use for dozens of different page selects tree branches... Do all of your templates that require containers have different fields? -
Part III: Using YAML (part of structured data module). 1.) Install the module (make sure to install the new version, FieldtypeDataStructure) 2.) create the field for it (ex. settings_ds) 3.) Add some settings - these can be more sophisticated/nested than the settings above, because of the YAML structure options: - name: address street: 27 Hawthorne Lane city: New York state: NY zip: 10982 phones: main: (999) 888 9874 fax: (555) 548-5647 - name: social_media facebook: https://www.facebook.com twitter: https://twitter.com - name: global site_title: My Awesome Site tagline: Tulips Rule 4.) Get the field into your template: $settings_ds = $pages->get(1644)->settings_ds; 5a.) Option 1: Auto populate the $vars foreach($settings_ds as $setting) ${$setting->name} = $setting; 5b.) Option 2: Query the field with PW selectors (this is awesome): $address = $settings_ds->get("name=address"); $social_media = $settings_ds->get("name=social_media"); $global = $settings_ds->get("name=global"); this is cool because you can keep all the parts of a setting together as a group, and have multiple parameters like this: // address echo $address->street; echo $address->city; echo $address->state; echo $address->zip; echo $address->phones->main; echo $address->phones->fax; // social media echo $social_media->facebook; echo $social_media->twitter; // global echo $global->site_title; echo $global->tagline;
-
@ozwim - awesome module, this will make me lose sleep. Is there any way to use get on the yaml without having to first create a new wire array and add the yaml to that.. for example, i have this YAML: - name: address street: 27 Hawthorne Lane city: New York state: NY zip: 10982 phones: main: (999) 888 9874 fax: (555) 548-5647 - name: facebook url: http://www.facebook.com - name: site_title value: My Awesome Site and i'm outputting like this for now, since it works: $settings_yaml = $pages->get(1644)->settings_yaml; $settings = new WireArray(); foreach($settings_yaml as $sy) { $settings->add($sy); } $site_title = $settings->get("name=site_title")->value; $address = $settings->get("name=address"); $facebook = $settings->get("name=facebook"); echo $address->street; echo $address->city; echo $address->phones->main; echo $address->phones->fax; echo $facebook->url; echo $site_title; TIA!
-
I almost never use the default menu listing of the page tree; i make a custom page tree somewhere under a "Menus" page and then generate the menus there, as is mentioned by Kongondo above... works like a charm.. if you need help building it, let me know!
- 75 replies
-
- 2
-
-
Limit page children to specific template (as page option)
Macrura replied to MarcinP's topic in API & Templates
@MarcinP - i don't see any problem with this, and you can always use the alternate template filename to limit the # of actual file templates you need to create... my philosophy is that I create as many of those family type relations templates as necessary; I don't think it really affects anything... -
Part II: Using a Profields Table [Note: this part requires you to own ProFields] 1.) Setup a field of type table for settings, I call it settings_table. It will have 2 columns, setting and value 2.) add it to your template (example would be if you had a settings template). 3.) Add some settings.. | site_title | My Great Site | |------------|-------------------------| | phone | (666) 777-8888 | |------------|-------------------------| | slogan | Tulips Rule | |------------|-------------------------| | facebook | http://www.facebook.com | 3.) Place this code in your _init.php or wherever you have global stuff.. replace the page number with the appropriate page number: $settings_table = $pages->get(1020)->settings_table; foreach($settings_table as $row) { ${$row->setting} = $row->value; } now you can do this: echo $site_title echo $phone echo $slogan echo $facebook - - - ...and one might wonder, what is to prevent a client from inadvertently changing the setting name or even deleting a critical setting and consequently breaking their site? with some jQuery, and the help of admin custom files (courtesy of martijn-geerts) you can disable any existing setting name from being edited. or deleted; add this to your AdminCustomFiles/ProcessPageEdit.js file: $(function(){ $('li.Inputfield_settings_table tr').each(function(){ setting = $(this).find('input[name*="_setting"]'); value = $(this).find('input[name*="_value"]').val(); icon = $(this).find('i.InputfieldTableRowDeleteLink'); if(value) { setting.addClass("disabled").attr('readonly', true); icon.removeClass("InputfieldTableRowDeleteLink fa-trash-o").addClass("fa-lock"); } }); }); this does assume that the table is named settings_table, the setting column is named "setting" and the value column is named "value". you can also add this to your AdminCustomFiles/ProcessPageEdit.css li.Inputfield_settings_table tr input.disabled { background-color: #e8e5e5 !important; color: #949494!important; } Here is a screenshot of this in action: Edit: added instructions to protect the settings names, prevent deletion, and change the color to differentiate the field status.
-
@adrian - yes, i love that YAML thing; and as I see it there are maybe 4-5 good ways to do settings, depending on the site and the scenario; I usually use a profields table, and have 2 columns, and do a similar code as above to get the $vars, and i'm using this for a lot of things like slider settings, site settings, settings for javascript plugins etc.. where i need to have a ton of settings without much effort... For some things that are mission critical I make fields, especially if the setting can use a color picker, rangeslider, or select. the delimited textarea is good for beginners who maybe don't have profields, and who need a quick easy way to have some editable settings in the b/e.. and there should be an easy way to use the YAML field to do this; i guess i should try it and do another tutorial for using that for settings...
-
Needed to show someone how to quickly setup some settings for various things in a simple text area: could be used for slider settings, site settings, etc; What it does: gives you a matching variable for each key of each line... 1.) setup a textarea field for the settings ; i'm calling it settings_ta 2.) add delimited settings, 1 per line; i use a pipe (|) delimiter; example: address|some info here facebook|https://www.facebook.com twitter|https://twitter.com phone|(999) 999-9999 3.) in your _init.php, get the settings - replace the page number and the name of your settings field: $settings_ta = $pages->get(1644)->settings_ta; $settings_lines = explode(PHP_EOL, $settings_ta); foreach($settings_lines as $settings_row) { $settings_pair = explode('|', $settings_row); ${trim($settings_pair[0])} = trim($settings_pair[1]); } more condensed version, for those of you who like brevity... foreach(explode(PHP_EOL, $pages->get(1644)->settings_ta) as $settings_row) { $settings_pair = explode('|', $settings_row); ${trim($settings_pair[0])} = trim($settings_pair[1]); } now you can do this in your templates: echo $address; echo $facebook; echo $twitter; echo $phone; Edit: made the code simpler....; 2nd edit - added trim to support using ace editor with tabs Addendum: as an added convenience, you could use the Ace text editor module which would give you a monospaced text field and the ability to use tabs for your settings, which could be more readable and easier to edit. The code has been updated to support this by trimming the exploded strings prior to generating the variable/value. address | some info here facebook | http://www.facebook.com twitter | http://twitter.com phone | (999) 999-9999
-
i wish there was a love button
-
You can make your custom sharing widgets using sharrre and PW.. doesn't take long! 1.) Download http://sharrre.com/ 2.) put sharrre.php in templates 3.) put jquery.sharrre.min.js in your scripts folder. 4.) add the new template to PW 5.) add new hidden page using that template; call it anything (example 'sharrre') 6.) include the script in your output; 7.) in your custom js file setup your js; make sure to put in the correct urlCurl to your page using the sharrre.php for example: /*-----------------------------------------------------------------------------------*/ /* SHARRRE /*-----------------------------------------------------------------------------------*/ $('#shareme').sharrre({ share: { twitter: true, facebook: true, googlePlus: true }, urlCurl: '/sharrre/', template: '<div class="box"><div class="left">Share</div><div class="middle"><a href="#" class="facebook">f</a><a href="#" class="twitter">t</a><a href="#" class="googleplus">+1</a></div><div class="right">{total}</div></div>', enableHover: false, enableTracking: true, render: function(api, options){ $(api.element).on('click', '.twitter', function() { api.openPopup('twitter'); }); $(api.element).on('click', '.facebook', function() { api.openPopup('facebook'); }); $(api.element).on('click', '.googleplus', function() { api.openPopup('googlePlus'); }); } }); Note: there are other themes - see the website... grab the CSS that goes with this JS setup: http://sharrre.com/example2.html 8.) somewhere on your page, put the relevant markup: <div id="sharrre"> <div id="shareme" data-url="<?php echo $page->httpUrl?>" data-text="Share this page"></div> </div> works for me on 3 sites so far.. - - - N.B. There is now a comprehensive module for social sharing buttons by Soma which is probably easier to setup and more flexible, though using Sharrre can still have some applications. Also, it is possible that Sharrre is no longer maintained and may not still work without some intervention... not sure as I have not researched this issue..
-
@joss - like your idea; just spent 2 hrs making PDF files with screenshots, arrows and callouts for a client so they can go in and start editing their site.. of course I could make some a custom admin page and put a sidebar link to documentation; but an all-in-one dedicated module would be nice where you could add pages to some part of the tree for all of the docs and then have the module generate the welcome screen for the docs, with list view... (sorry to post after you closed this)..