Welcome Guest, Not a member yet? Register   Sign In
How do I replace front-end views with JSONs in Codeigniter 3?
#1

(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?
Reply
#2

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.
CodeIgniter 4 tutorials (EN/FR) - https://includebeer.com
/*** NO support in private message - Use the forum! ***/
Reply
#3

(08-15-2019, 06:17 PM)includebeer Wrote: 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.

I do not want to load a Codeigniter view. I want to spit out clean JSON data instead, then use Vue or AngularJS to display the data publicly in a nice way.
Reply
#4

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));
Reply
#5

(This post was last modified: 08-20-2019, 09:57 PM by Ajax30.)

(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.
Reply
#6

/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}]}
     ]
}
Reply
#7

(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));

Reply
#8

(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?
Reply
#9

(This post was last modified: 08-22-2019, 01:48 AM by ciadmin.)

Quote:Great. It works as desired. 

How can I make the json pretty, from the controller?


https://www.php.net/manual/en/function.json-encode.php
PHP Code:
public function index() {
   $data['something'] = 'whatever is appropriate';
   $this->output->set_content_type('application/json')->set_output(json_encode($data,JSON_PRETTY_PRINT));

Reply
#10

(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.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB