-
Ajax30 Member
  
-
Posts: 71
Threads: 46
Joined: Aug 2017
Reputation:
0
08-15-2019, 01:12 PM
(This post was last modified: 08-15-2019, 01:14 PM by Ajax30.)
I am working on a blog application with Codeigniter 3.1.8.
Currently, its admin area is well separated from the frontend. Both the backend (admin area) and the frontend display data using "classic" Codeigniter views.
I thought It would be great if I could replace the classic views of the frontend with JSONS so that they could be formated and displayed using frontend technologies like Vue or Angular, independently of the classic Codeigniter views, that I would only use on the backend.
The JSONS should be spat out directly from the controllers involved in the functioning of the posts and single post pages, without the help of the views.
I need a reliable method for this, as the controllers are quite complex. Here is the Posts controller:
Code: class Posts extends CI_Controller {
public function __construct()
{
parent::__construct();
}
private function _initPagination($path, $totalRows, $query_string_segment = 'page') {
//load and configure pagination
$this->load->library('pagination');
$config['base_url'] = base_url($path);
$config['query_string_segment'] = $query_string_segment;
$config['enable_query_strings'] =TRUE;
$config['reuse_query_string'] =TRUE;
$config['total_rows'] = $totalRows;
$config['per_page'] = 12;
if (!isset($_GET[$config['query_string_segment']]) || $_GET[$config['query_string_segment']] < 1) {
$_GET[$config['query_string_segment']] = 1;
}
$this->pagination->initialize($config);
$limit = $config['per_page'];
$offset = ($this->input->get($config['query_string_segment']) - 1) * $limit;
return ['limit' => $limit, 'offset' => $offset];
}
public function index() {
//call initialization method
$config = $this->_initPagination("/", $this->Posts_model->get_num_rows());
$data = $this->Static_model->get_static_data();
$data['pages'] = $this->Pages_model->get_pages();
$data['categories'] = $this->Categories_model->get_categories();
//use limit and offset returned by _initPaginator method
$data['posts'] = $this->Posts_model->get_posts($config['limit'], $config['offset']);
$this->load->view('partials/header', $data);
$this->load->view('posts');
$this->load->view('partials/footer');
}
public function search() {
// Force validation since the form's method is GET
$this->form_validation->set_data($this->input->get());
$this->form_validation->set_rules('search', 'Search term', 'required|trim|min_length[3]',array('min_length' => 'The Search term must be at least 3 characters long.'));
$this->form_validation->set_error_delimiters('<p class = "error search-error">', '</p>
');
// If search fails
if ($this->form_validation->run() === FALSE) {
return $this->index();
} else {
$expression = $this->input->get('search');
$posts_count = $this->Posts_model->search_count($expression);
$query_string_segment = 'page';
$config = $this->_initPagination("/posts/search", $posts_count, $query_string_segment);
$data = $this->Static_model->get_static_data();
$data['pages'] = $this->Pages_model->get_pages();
$data['categories'] = $this->Categories_model->get_categories();
//use limit and offset returned by _initPaginator method
$data['posts'] = $this->Posts_model->search($expression, $config['limit'], $config['offset']);
$data['expression'] = $expression;
$data['posts_count'] = $posts_count;
$this->load->view('partials/header', $data);
$this->load->view('search');
$this->load->view('partials/footer');
}
}
public function byauthor($authorid){
$data = $this->Static_model->get_static_data();
$data['pages'] = $this->Pages_model->get_pages();
$data['categories'] = $this->Categories_model->get_categories();
$data['posts'] = $this->Posts_model->get_posts_by_author($authorid);
$data['posts_count'] = $this->Posts_model->posts_by_author_count($authorid);
$data['posts_author'] = $this->Posts_model->posts_author($authorid);
$this->load->view('partials/header', $data);
$this->load->view('posts_by_author');
$this->load->view('partials/footer');
}
public function post($slug) {
$data = $this->Static_model->get_static_data();
$data['pages'] = $this->Pages_model->get_pages();
$data['categories'] = $this->Categories_model->get_categories();
$data['posts'] = $this->Posts_model->sidebar_posts($limit=5, $offset=0);
$data['post'] = $this->Posts_model->get_post($slug);
if ($data['categories']) {
foreach ($data['categories'] as &$category) {
$category->posts_count = $this->Posts_model->count_posts_in_category($category->id);
}
}
if (!empty($data['post'])) {
// Overwrite the default tagline with the post title
$data['tagline'] = $data['post']->title;
// Get post comments
$post_id = $data['post']->id;
$data['comments'] = $this->Comments_model->get_comments($post_id);
$this->load->view('partials/header', $data);
$this->load->view('post');
} else {
$data['tagline'] = "Page not found";
$this->load->view('partials/header', $data);
$this->load->view('404');
}
$this->load->view('partials/footer');
}
}
So, I need a rock-solid method to spit all that as JSON at once.
What is the best approach for this?
-
includebeer CodeIgniter Team
-
Posts: 1,018
Threads: 18
Joined: Oct 2014
Reputation:
40
This question doesn’t make any sense. There’s no “rock-solid method” that will do the magic for you. It’s a simple process: you load a view, the javascript makes an ajax request to get the data it needs, the controller respond with json data, the javascript read that and plug the data in the DOM.
-
jreklund Administrator
      
-
Posts: 1,408
Threads: 3
Joined: Aug 2017
Reputation:
43
/application/controller/Api.php
PHP Code: <?php defined('BASEPATH') OR exit('No direct script access allowed');
class Api extends CI_Controller { public function index() { $this->load->view('api'); }
public function json() { $data = file_get_contents(FCPATH.'../sampleData.json'); $data = json_decode($data); $this->output ->set_content_type('application/json', 'UTF-8') ->set_output(json_encode($data)); } }
/application/views/api.php
Code: <html>
<head>
<!--Load the AJAX API-->
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
// Load the Visualization API and the piechart package.
google.charts.load('current', {'packages':['corechart']});
// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var jsonData = $.ajax({
url: "/index.php/api/json",
dataType: "json",
async: false
}).responseText;
// Create our data table out of JSON data loaded from server.
var data = new google.visualization.DataTable(jsonData);
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, {width: 400, height: 240});
}
</script>
</head>
<body>
<!--Div that will hold the pie chart-->
<div id="chart_div"></div>
</body>
</html>
/sampleData.json
Code: {
"cols": [
{"id":"","label":"Topping","pattern":"","type":"string"},
{"id":"","label":"Slices","pattern":"","type":"number"}
],
"rows": [
{"c":[{"v":"Mushrooms","f":null},{"v":3,"f":null}]},
{"c":[{"v":"Onions","f":null},{"v":1,"f":null}]},
{"c":[{"v":"Olives","f":null},{"v":1,"f":null}]},
{"c":[{"v":"Zucchini","f":null},{"v":1,"f":null}]},
{"c":[{"v":"Pepperoni","f":null},{"v":2,"f":null}]}
]
}
-
ciadmin Cat Herder
      
-
Posts: 1,319
Threads: 21
Joined: Jan 2014
Reputation:
71
(08-20-2019, 09:54 PM)Ajax30 Wrote: (08-20-2019, 11:21 AM)ciadmin Wrote: What about something like https://www.codeigniter.com/user_guide/l...ntent_type
Instead of loading any view at all, each controller method would build its "view data" as $data, and then
$this->output->set_content_type('application/json')->set_output(json_encode($data));
How would that code look exactly, in the context of my Posts controller? For the index() method, for instance.
In your Posts::index() ...
Old code
PHP Code: public function index() {
$data['something'] = 'whatever is appropriate'; $this->load->view('myhomepage',$data); }
would be exactly replaced by
PHP Code: public function index() { $data['something'] = 'whatever is appropriate'; $this->output->set_content_type('application/json')->set_output(json_encode($data)); }
-
Ajax30 Member
  
-
Posts: 71
Threads: 46
Joined: Aug 2017
Reputation:
0
(08-21-2019, 01:21 PM)ciadmin Wrote: (08-20-2019, 09:54 PM)Ajax30 Wrote: (08-20-2019, 11:21 AM)ciadmin Wrote: What about something like https://www.codeigniter.com/user_guide/l...ntent_type
Instead of loading any view at all, each controller method would build its "view data" as $data, and then
$this->output->set_content_type('application/json')->set_output(json_encode($data));
How would that code look exactly, in the context of my Posts controller? For the index() method, for instance.
In your Posts::index() ...
Old code
PHP Code: public function index() {
$data['something'] = 'whatever is appropriate'; $this->load->view('myhomepage',$data); }
would be exactly replaced by
PHP Code: public function index() { $data['something'] = 'whatever is appropriate'; $this->output->set_content_type('application/json')->set_output(json_encode($data)); }
Great. It works as desired.
How can I make the json pretty, from the controller?
-
cartalot You Can't Fax Glitter
   
-
Posts: 354
Threads: 13
Joined: Nov 2014
Reputation:
17
08-23-2019, 01:42 PM
(This post was last modified: 08-23-2019, 01:48 PM by cartalot.)
Something to consider if you end up using Vue - another alternative is to create the basic template of the page using a Codeigniter view - and then in Vue use Axios to call the resources that you need from the database for that page. Depending on your situation this can be best of both worlds because..
1) your initial View page loads very quickly for the user.
2) if there are any errors with Vue or it calling the db, etc etc - your page has already loaded so the errors are confined to the Vue id etc. Much more elegant for displaying errors, especially for multi step processes like forms. Also contains any slow responses from 3rd party apis.
3) you can create the basic template for the page with whatever you are already using (versus having to recreate every single element all over again in Vue)
4) you can still create awesome dynamic content with Vue. like you can do a search -> find -> list results in the Vue code. but because its inside the codeigniter view file - there is no browser refresh - so then it feels very fast for the user.
|