Creating Add Feature for ReadLater App

by Ruchita Rathi

This week I completed the add functionality for the ReadLater App thanks to the generous help from the community especially LEDfan, brantje, and Raydiation.

This blog post provides details on how I built this feature.

I started with understanding how existing apps work on the ownCloud platform. For this feature, I looked at bookmarksPassman, and the News app. To develop the front end of the readlater app, I looked at the existing News app implementation and created this front-end for ReadLater app:


ReadLater App Front-end

For this purpose, I looked at the docs for manipulating CSS and HTML: ownCloud App Development – Front End.

For the front end development, you need to start with the /templates/main.php file in your app.

While developing the front end, you might come across the “Template file not found” exception:

Template file error owncloud app development


This exception happens when you specify incorrect route in your appinfo/app.php file. To resolve this error, you must specify correct route like so, for the readlater app, the index page is specified as:

'href' => \OCP\Util::linkToRoute(''),

I also came across the “no app name ” error. This error is caused because the repo on github is ReadLater and when I cloned it, the directory was called ReadLater, but ownCloud only allows readlater.

I then added the functionality to save the content in readlater app, however, I was not able to insert values into the database. For creating the backend, I looked at Passman’s implementation at:

I also saw this error in the log file (to access the log file, go to http://$your-owncloud-server/data/owncloud.log)

{"app":"PHP","message":"Cannot modify header information - headers already sent at \/var\/www\/core\/lib\/private\/appframework\

Per discussion with Raydiation on the IRC channel, it was probably because I had removed the annotations from the Controller.

The App Framework also provides a simple baseclass for adding controllers:OCA\AppFramework\Controller\Controller. Controllers connect your view (templates) with your database and contain the logic of your app. Controllers themselves are connected to one or more routes. Controllers go into the controller/ directory.

For security reasons, all security checks for controller methods are turned on by default. To explicitly turn off checks, you must use exemption annotations above the desired method.

Possible Annotations contain:

  • @CSRFExemption: Turns off the check for the CSRF token. Only use this for the index page!
  • @IsAdminExemption: Turns off the check if the user is an admin
  • @IsLoggedInExemption: Turns off the check if the user is logged in
  • @IsSubAdminExemption: Turns off the check if the user is a subadmin
  • @Ajax: Use this for Ajax Requests. It prevents the unneeded rendering of the apps navigation and returns error messages in JSON format

It is important to add your controller to the dependency injection container in dependency injection/dicontainer.php. (source: ownCloud Controllers)

To check if the Add button is working, I used the Network tab of the developer tools in my browser.  For the above error in addition to the annotations, I was also using incorrect route.

Routes are declared in appinfo/routes.php. Routing connects your URLs with your controller methods and allows you to create constant and nice URLs. Its also easy to extract values from the URLs. For more information on how to implement routes in your app, see: ownCloud Routes.

After fixing  the routes, I was still seeing a blank page even after the POST request went through fine.



Turns out, I missed the generateURL function in my JS file.

To send requests to ownCloud the base URL where ownCloud is currently running is needed.  Full URLs can be generated by using:

var authorUrl = OC.generateUrl('/apps/myapp/authors/1');

For the readlater app’s Add url, my code in the js file is now:

function saveData(){
	type: "POST",
  	url: OC.generateUrl('/apps/readlater/add/url'),
  	data: {url: $('#url').val()}
    }).done(function( msg ) {
 alert( "Your content was saved: " + msg );


I also encountered this exception:

{"app":"index","message":"Doctrine\\DBAL\\DBALException: An exception occurred while executing 'INSERT INTO `oc_readlater_items` (`url`)
VALUES (?)':\n\nSQLSTATE[42S02]: Base table or view not found: 1146 Table 
'owncloud.oc_readlater_items' doesn't exist","level":4,"time":"2014-07-19T13:02:52+00:00"}

To fix this, LEDfan suggested adding a file “version” in the appinfo dir:

Also, it is important to note that whenever you change anything in your appinfo/database.xml file, you must increment the version numbers in both the version file and the appinfo/info.php file.

Thanks to the help from the ownCloud IRC channels, I was able to complete the add URL feature for ReadLater app.