How would you approach Projects + Images modules
Hi! I'm getting into Fuel CMS for the first time, and really have a very basic question. I'm set out to build a portfolio site which typically has projects. The projects module, in this case, would be similar to the one provided in the examples, with the difference that I would like to relate/connect records: in this case, images. So I would need a way to add x amount of images to any project.
Then, in the frontend, I would call each project and loop through the project's images and hook it up to a jquery gallery or slider.
How would you approach this? I'm interested in the module approach and in particular, in a way to have infinite amount of images related to that project, then be able to sort those images in the project, or even delete them.
thanks!
Comments
$fields['image'] = array('type' => 'file', 'class' => 'multifile', 'upload_path' => assets_server_path('properties/{type}/{slug}/big/', 'images'));
This gives us the ability to upload as many images as you want. You'll notice the {type}/{slug} which are placeholders for values that belong to the record. This allows you to upload the images to a folder like assets/images/properties/web/my-fuel-web-project/big/, where "web" is the type associated with the project and "my-fuel-web-project" is the slug value (these placeholder values like 'slug' must not be empty... if they are, you can use the on_before_post model hook to make sure they have a value e.g. $_POST['slug'] =url_title($_POST['name'], 'dash', TRUE);).
Then to further process the images you can use the model's on_after_post hook. This gives you a place to perhaps rename the images or create thumbnails. I've posted below a snippet of an older project we've used a similar method on that may help (I'm sure there is a better way we could write this now though:):
function form_fields($values = array()) { $fields = parent::form_fields(); $CI =& get_instance(); $CI->load->model('clients_model'); $client_options = $CI->clients_model->options_list('id', 'name', array('published' => 'yes'), 'name'); $fields['client_id'] = array('label' => 'Client', 'type' => 'select', 'options' => $client_options, 'class' => 'add_edit', 'first_option' => 'Select or Add a Client...'); $fields['project_url']['label'] = 'Project URL'; $fields['featured']['order'] = 9998; $main_image_after_html = ''; $images_after_html = ''; if (!empty($values['id'])) { $project = $this->find_by_key($values['id']); if (!empty($project->main_image)) { $main_image_after_html = '<br /><img src="'.$project->main_image.'" />'; } if (!empty($project->images)) { $assets_arr = array(); foreach($project->images as $thumb => $img) { $name = end(explode('/', $img)); $assets_arr[] = '<a href="'.$img.'"><img src="'.$thumb.'" /></a>'; } $images_after_html = '<br />'.implode(' ', $assets_arr); } } $upload_path = assets_server_path('work/{image_folder}/', 'images'); $fields['main_image_upload'] = array('after_html' => $main_image_after_html, 'filename' => 'work_{image_folder}', 'label' => 'Upload the main image', 'upload_path' => $upload_path, 'type' => 'file', 'overwrite' => TRUE, 'comment' => 'Uploaded a main image associated with this project', 'order' => 9998); $fields['image_upload'] = array('after_html' => $images_after_html, 'label' => 'Upload an image', 'upload_path' => $upload_path, 'type' => 'file', 'class' => 'multifile', 'overwrite' => TRUE, 'comment' => 'Uploaded images associated with this project', 'order' => 9999); $fields['published']['order'] = 10000; unset($fields['permalink']); return $fields; } function on_before_post() { $CI =& get_instance(); if (empty($_POST['name'])){ $CI->load->model('clients_model'); $client = $CI->clients_model->find_by_key($_POST['client_id']); if (!empty($client->name)) { $_POST['name'] = $client->name; } } if (empty($_POST['image_folder'])) { $_POST['image_folder'] = url_title($_POST['name'], 'underline', TRUE); } if (empty($_POST['permalink'])) { if (!empty($_POST['image_folder'])){ $_POST['permalink'] = $_POST['image_folder']; } else { $_POST['permalink'] = url_title($_POST['name'], 'dash', TRUE); } } // hacky... for changing the $_POST[image_upload_path] $asset_folders = $CI->asset->assets_folders; $upload_path = assets_server_path().$asset_folders['images'].'work/'.$_POST['image_folder'].'/'; if (!empty($_FILES)) { foreach($_FILES as $file => $fileinfo) { $_POST[$file.'_upload_path'] = $upload_path; $_POST['main_image_upload_path'] = $upload_path; $_POST['image_upload_path'] = $upload_path; } } } function on_after_post($values) { $CI =& get_instance(); $CI->load->library('image_lib'); $project = $this->find_by_key($values['id']); // process other images $i = 0; foreach($_FILES as $file => $file_info) { if ($file_info['error'] == 0) { $upload_path = assets_server_path($project->get_img_path(), 'images'); if (!file_exists($upload_path)) { mkdir($upload_path, DIR_WRITE_MODE, TRUE); } // filter out for the main image if (strncmp($file, 'main_image_upload', 17) === 0) { $filename_no_ext = $values['main_image_upload_filename']; $ext = 'jpg'; $filename = $values['main_image_upload_filename'].'.'.$ext; $img_folder = $upload_path; $src_img = $upload_path.$filename; // resize to proper dimensions $config = array(); $config['source_image'] = $src_img; $config['create_thumb'] = FALSE; $config['new_image'] = ''; $config['width'] = 160; $config['height'] = 160; $config['master_dim'] = 'auto'; $config['maintain_ratio'] = TRUE; $CI->image_lib->clear(); $CI->image_lib->initialize($config); if (!$CI->image_lib->resize_and_crop()) { $this->add_error($CI->image_lib->display_errors()); } } // filter out all the asset upload files to create the thumbnail if (strncmp($file, 'image_upload', 12) === 0) { $filename = strtolower($file_info['name']); $filename_arr = explode('.', $filename); $filename_no_ext = $filename_arr[0]; $ext = $filename_arr[1]; $img_folder = $upload_path; $src_img = $upload_path.$filename; // resize to proper dimensions $config = array(); $config['source_image'] = $src_img; $config['create_thumb'] = FALSE; $config['new_image'] = ''; $config['width'] = 594; $config['height'] = 472; $config['master_dim'] = 'auto'; $config['maintain_ratio'] = TRUE; $CI->image_lib->clear(); $CI->image_lib->initialize($config); if (!$CI->image_lib->resize()) { $this->add_error($CI->image_lib->display_errors()); } // now create the thumbnail using our resize_and_crop custom addon to the Image_lib CI class $config = array(); $config['source_image'] = $src_img; $config['create_thumb'] = TRUE; $config['thumb_marker'] = '_thumb'; $config['width'] = 73; $config['height'] = 49; $CI->image_lib->clear(); $CI->image_lib->initialize($config); if (!$CI->image_lib->resize()) { $this->add_error($CI->image_lib->display_errors()); } // now move thumb into the thumb directory... but first create thumbnail directory if it doesn't exist $thumb_folder = $upload_path.'thumbs/'; $old_thumb_path = $upload_path.$filename_no_ext.'_thumb.'.$ext; $new_thumb_path = $thumb_folder.$filename_no_ext.'_thumb.'.$ext; if (!file_exists($thumb_folder)) { mkdir($thumb_folder, DIR_WRITE_MODE, TRUE); } @rename($old_thumb_path, $new_thumb_path); } } } return $values; } return $values; }
Please the snippet you posted above is wonderful, but please can you explain it some more, such as:
$upload_path = assets_server_path('work/{image_folder}/', 'images');
what is "{image_folder}" how would i implement something similar (that is, how could i make it the name of the album ? say i had a field for album name, how could i get the
"{image_folder}" and or a variable take on the value of the album field ?)
$upload_path = assets_server_path($project->get_img_path(), 'images');
where is the method get_img_path() located or defined ?
Thanks in advance.
A nice break down will really aid me in my learning in fuelcms, php and with a project.
The get_img_path() method is found on the record level class of the project (not shown above).
class Projects_model extends Base_module_model { //..... PROJECT MODEL CODE GOES HERE INCLUDING THE ABOVE... } class Project_model extends Base_module_record { function get_url() { return site_url('showcase/project/'.$this->slug); } function get_image_path() { return img_path('projects/'.$this->image); } function get_thumb() { $thumb = $this->_parent_model->thumb_name($this->image); return img_path('projects/'.$thumb); } }
This is very interesting. I am enjoying fuel cms big time. I love all the helpers and the optin controller, everything.
I cant wait till i am good at this.
for some reason this is not working for me
$thumb_img = assets_server_path('galleries/{album_name}/thumb/'.$data['file_name'], 'images');
I get make sure the directory or image is wirteable.
please what do i do ?
the directory is writeable (777)
please help.
So please how can i get {album_name} to be a working variable ? {album_name} is dynamic.
{album_name} works when i am not using the image manipulation class.
Thanks in advance.
but its not working, it is not translating {album_name} to the value stored in it.
let me post the entire code i have so far
function form_fields($values = array())
{
$fields = parent::form_fields($values);
$CI =& get_instance();
$CI->load->model('tn3_gallery_albums_model');
$_album_options = $CI->tn3_gallery_albums_model->options_list('album_name', 'album_title');
$fields['album_name'] = array('type' => 'select', 'options' => $_album_options);
$img_large_upload_path = assets_server_path('galleries/{album_name}/', 'images');
$fields['img_large'] = array('type' => 'file', 'upload_path' => $img_large_upload_path, 'overwrite' => TRUE);
//$img_thumb_upload_path = assets_server_path('galleries/{album_name}/thumb/', 'images');
//$fields['img_thumb'] = array('type' => 'file', 'upload_path' => $img_thumb_upload_path, 'overwrite' => TRUE);
//$fields['image_thumb_upload'] = array('type' => 'file', 'upload_path' => $upload_path, 'overwrite' => TRUE);
//$fields['image_large'] = array('type' => 'file', 'class' => 'multifile', 'upload_path' => assets_server_path('galleries/{type}/', 'images'));
//$fields['img_thumb']['class'] = 'asset_select images/galleries/{album_name}/thumb/';
//$fields['img_large']['class'] = 'asset_select images/galleries/{album_name}/';
//$fields['image_upload']['before_html'] = '';
return $fields;
}
function on_after_post($values)
{
$CI =& get_instance();
$CI->load->library('image_lib');
// create the thumbnail if an image is uploaded
if (!empty($CI->upload))
{
$data = $CI->upload->data();
if (!empty($data['full_path']))
{
//$thumb_img = assets_server_path('galleries/{album_name}/thumb/'.$data['file_name'], 'images');
$thumb_img = assets_server_path('galleries/{album_name}/'.$this->thumb_name($data['file_name']), 'images');
// resize to proper dimensions
$config = array();
$config['source_image'] = $data['full_path'];
$config['create_thumb'] = FALSE;
//$config['new_image'] = $thumb_img;
$config['width'] = 800;
$config['height'] = 800;
$config['master_dim'] = 'auto';
$config['maintain_ratio'] = TRUE;
$CI->image_lib->clear();
$CI->image_lib->initialize($config);
if (!$CI->image_lib->resize())
{
$this->add_error($CI->image_lib->display_errors());
}
// create thumb
$config = array();
$config['source_image'] = $data['full_path'];
$config['create_thumb'] = FALSE;
$config['new_image'] = $thumb_img;
$config['width'] = 114;
$config['height'] = 72;
$config['master_dim'] = 'auto';
$config['maintain_ratio'] = TRUE;
$CI->image_lib->clear();
$CI->image_lib->initialize($config);
if (!$CI->image_lib->resize())
{
$this->add_error($CI->image_lib->display_errors());
}
}
}
return $values;
}
function thumb_name($image)
{
return preg_replace('#(.+)(\.jpg|\.png)#U', '$1_thumb$2', $image);
}
thanks again
$thumb_img = assets_server_path('galleries/'.$CI->input->post('album_name').'/'.$this->thumb_name($data['file_name']), 'images');
The following is referencing the uploaded path 'album_name_path' $_POST variable that automatically gets created when uploading a file and will have the properly substituted {album_name} value:
$thumb_img = $CI->input->post('album_name_path').'/'.$this->thumb_name($data['file_name']), 'images');