{"id":37,"date":"2015-04-12T18:21:00","date_gmt":"2015-04-12T16:21:00","guid":{"rendered":"https:\/\/daniel.liljeberg.io\/?p=37"},"modified":"2021-04-01T22:02:08","modified_gmt":"2021-04-01T20:02:08","slug":"how-to-develop-plugins-for-osclass","status":"publish","type":"post","link":"https:\/\/daniel.liljeberg.io\/sv\/2015\/04\/12\/how-to-develop-plugins-for-osclass\/","title":{"rendered":"How to develop Plugins for Osclass"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">As described in&nbsp;<a href=\"https:\/\/daniel.liljeberg.io\/2015\/03\/28\/osclass\/\" target=\"_blank\" rel=\"noreferrer noopener\">my earlier post<\/a>, Osclass is a free, open-source, web application written in PHP for classified ads. One of the strong sides of it is that you have the options to create and install custom plugins to extend and alter the behavior of the application. There is an integrated market where existing plugins can be easily downloaded and installed.&nbsp;<a href=\"http:\/\/market.osclass.org\/user\/profile\/665\" target=\"_blank\" rel=\"noreferrer noopener\">Here are some of my own creations<\/a>&nbsp;(more are being updated and are on the way).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I started by creating plugins for my own personal use. Since I was the only one using them I often left configuration options in configuration files instead of building full fledged admin interfaces.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But as time went by people started asking me if they could have a copy of different plugins I had made. This would require me to add functionality to them to make them easily managed by other&nbsp;people. Often people who weren\u2019t developers.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One thing that struck me when I was writing new plugins was the&nbsp;<a href=\"http:\/\/doc.osclass.org\/How_to_create_a_plugin\" target=\"_blank\" rel=\"noreferrer noopener\">official way<\/a>&nbsp;that they are to be written which I thought had several issues. Since I never thought I would make many plugins, and especially not any released ones,&nbsp;I swallowed my pride and stuck to their regime. But now when I found myself planning more plugins I felt I wanted to streamline the experience of creating plugins for Osclass.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Bellow I will walk you through creating a very simple plugin using the&nbsp;<em>official way<\/em>. Later I will describe the ideas I have come up with to further streamline and isolate the plugins. The plugin we will be building will be a simple&nbsp;<strong>Hello World<\/strong>&nbsp;type plugin with the added option that we will dynamically set the message to show the user.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">File structure<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To create a plugin you first create a folder under the&nbsp;<strong>oc-content\/plugins<\/strong>&nbsp;folder, you can call it whatever you want. Within that folder you will need to place at least one file,&nbsp;<strong>index.php<\/strong><em>.&nbsp;<\/em>That is basically the only requirements regarding the file structure. You could add several files and libraries,&nbsp;java script files, css files etc.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conventions and guidelines<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Due to the fact that functions in your&nbsp;<strong>index.php<\/strong>&nbsp;will all be public, you do best in choosing a prefix that ensures that your function don\u2019t end up having the same name as any other function. If your plugin would contain a&nbsp;<strong>function&nbsp;install()<\/strong>&nbsp;and another plugin would do the same you would run into problems. Whatever convention you choose to pick your prefix is up to you. But prefixing with some developer identifier and\/or the plugin name is one way to go.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Later when we look at my alternate way of writing plugins we will see how we can pretty much circumvent this issue altogether.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Information block<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Each plugin in Osclass will have a information block in their&nbsp;<strong>index.php<\/strong>&nbsp;file.&nbsp;Here\u2019s an example of ours. More options exist and depending on your plugin not all will be needed.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/*\nPlugin Name: dliTest\nPlugin URI: http:\/\/www.foobar.org\/\nDescription: A small test plugin\nVersion: 1.0.0\nAuthor: Daniel Liljeberg\nAuthor URI: http:\/\/www.danieliljebergorg\/\nShort Name: dliTest\nPlugin update URI: dli-test\nSupport URI: http:\/\/support.foobar.org\n*\/<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This information is used internally by Osclass and is for example presented in the admin interface.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Make your plugin installable<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To make&nbsp;it possible for a plugin to be&nbsp;<strong>installed<\/strong>&nbsp;you have to add a piece of code to your&nbsp;<strong>index.php<\/strong>&nbsp;file.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">osc_register_plugin(osc_plugin_path(__FILE__), 'dliTest_install');<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">What this does is basically to register our plugin as being able to be installed and when a user chooses to install our plugin Osclass will run the function&nbsp;<strong>dliTest_install<\/strong>&nbsp;which we don\u2019t have yet. So let\u2019s add that to our&nbsp;<strong>index.php<\/strong>. In the same way we can add a function to be run when our plugin is uninstalled by a user. So we\u2019ll go ahead and do that to.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/*\nPlugin Name: dliTest\nPlugin URI: http:\/\/www.foobar.org\/\nDescription: A small test plugin\nVersion: 1.0.0\nAuthor: Daniel Liljeberg\nAuthor URI: http:\/\/www.danieliljebergorg\/\nShort Name: dliTest\nPlugin update URI: dli-test\nSupport URI: http:\/\/support.foobar.org\n*\/\n\n\/\/ Plugin functions\nfunction dliTest_install() {\n}\n\nfunction dliTest_uninstall() {\n}\n\n\/\/ Register hooks\nosc_register_plugin(osc_plugin_path(__FILE__), 'dliTest_install');\nosc_add_hook(osc_plugin_path(__FILE__).\"_uninstall\", 'dliTest_uninstall');<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now we are able to install and uninstall our plugin, although it won\u2019t actually do much.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Hooks<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Osclass uses the concept of&nbsp;<strong>hooks<\/strong>&nbsp;to enable you to hook in different parts of your plugin to be run at different points during the applications execution.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The normal syntax for&nbsp;registering a hook is<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">osc_add_hook('hook_name', 'function_name');<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Our call to&nbsp;<strong>osc_register_plugin<\/strong>&nbsp;in order to make it possible to install our plugin is actually just a special case for registering a hook to handle the installation. But it also handles some other functionality and is therefore wrapped in its own function.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As you can see the&nbsp;<strong>uninstall<\/strong>&nbsp;function above is registered using the&nbsp;<em>normal&nbsp;<\/em><strong>osc_add_hook()<\/strong>&nbsp;function, although it does have a bit of a special syntax where the name must be the&nbsp;<strong>your_plugins_folder\/index.php<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There are a ton of hooks you can use. For instance there are hooks that run in the page header, in the page footer, when the user is visiting an item page, when a new item is posted etc.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Look here for a&nbsp;<a href=\"https:\/\/web.archive.org\/web\/20150417013650\/http:\/\/doc.osclass.org\/Hooks\" target=\"_blank\" rel=\"noreferrer noopener\">complete list of hooks<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So a hook has a name and you supply it a function name. Then it makes code your have written in your plugin run at specific places in the application execution flow.&nbsp;This might look very magical, but it\u2019s actually quite easy. When you&nbsp;<strong>register a hook<\/strong>&nbsp;the function name you have provided is&nbsp;added to a list of functions to run when the hook with that name is run. It\u2019s basically like providing it a function pointer, but since&nbsp;<strong>php<\/strong>&nbsp;gladly executes a function in a multitude of ways you simply have to store the name of the function to run.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example these are all valid in php<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Define a function\nfunction helloWorld() {\necho \"Hello World\";\n}\n\n\/\/Calls function\nhelloWorld();\n\n\/\/Also calls function\n$funcName = \"helloWorld\";\n$funcName();<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Osclass then simply run a function at specific places that run a given hook.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">osc_run_hook(\"header\");<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now all functions registered to the&nbsp;<strong>header<\/strong>&nbsp;hook will be run at that place.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Common uses for this is to add things top the html header, like tags, loading scripts etc. Or hooking in and altering forms such as search and the form to post new items.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Deciding what runs when<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">One of the problems of the hooks is that there is no real way of telling when in the queue of functions to run your specific function is. It could be that it\u2019s very important that you run your code early, before other plugins have been able to run their functions for the same hook. To help facilitate this you can pass an optional third parameter to the&nbsp;<strong>osc_register_hook<\/strong>&nbsp;function. The third parameter will let you set the priority on a scale between 1 and 10 for the function you just registered. But do note that a&nbsp;registered function that has the same priority would make it hard for you to know for sure that your function will be the first to run.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Without knowing for sure I would guess that if two functions have the same priority and register for the same hook, the one registered&nbsp;first will run first. The one registered first will be the one&nbsp;owned by the plugin that was loaded before the other one. And the order in which the plugins load is very likely to be dependent on their alphabetical sorting of their directory name in the&nbsp;<strong>oc-content\/plugins<\/strong>&nbsp;folder.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So&nbsp;<strong>PluginA<\/strong>&nbsp;would load before&nbsp;<strong>PluginB<\/strong>&nbsp;and if&nbsp;<strong>PluginA<\/strong>&nbsp;registered&nbsp;<strong>foo<\/strong>&nbsp;to run at the&nbsp;<strong>hook header<\/strong>&nbsp;and&nbsp;<strong>PluginB<\/strong>&nbsp;registered&nbsp;<strong>bar<\/strong>&nbsp;to run at the&nbsp;<strong>same hook<\/strong>&nbsp;and they both had the&nbsp;<strong>same priority set<\/strong>,&nbsp;<strong>foo&nbsp;<\/strong>would most likely be&nbsp;<strong>run before bar<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Make our plugin print something<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Many plugins simply make use of existing hooks to output at specific places. For instance, to make our plugin write something when we look at the details of an item we could use the&nbsp;<strong>item_detail&nbsp;<\/strong>hook. This hook&nbsp;run at the middle of item\u2019s detail page.&nbsp;<strong>$item<\/strong>&nbsp;is passed as argument and can be used if needed.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">function dliTest_item_details_hook($item) {\n  echo '&lt;h3>Hello World&lt;\/h3>;\n}\nosc_add_hook('item_detail', 'dliTest_item_detail');<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">But what if we want to our plugin write&nbsp;<strong>Hello World<\/strong>&nbsp;in a page we have designed ourselves. In order to do that we will have to complete a couple of more steps.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Creating a&nbsp;<em>route<\/em>&nbsp;to our file<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A route is basically a way for you to tell Osclass that<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>This&nbsp;<strong>url<\/strong>&nbsp;should present the user with&nbsp;<strong>this file<\/strong><\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To do that in Osclass we use the function&nbsp;<strong>osc_add_route()<\/strong>. Read about it more on&nbsp;<a href=\"https:\/\/web.archive.org\/web\/20150417013650\/http:\/\/doc.osclass.org\/Using_routes_in_Osclass\" target=\"_blank\" rel=\"noreferrer noopener\">Using routes with Osclass<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So, let\u2019s add a quick route to a page called&nbsp;<strong>helloWorldPage.php<\/strong>&nbsp;and make the route accept a parameter names&nbsp;<strong>message<\/strong>&nbsp;consisting of&nbsp;<strong>characters between a-Z<\/strong>. I will name the route similarly to the actual file, but this is in no way needed.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">osc_add_route('helloWorldPage', 'helloWorldPage\/([a-zA-Z]+)', 'helloWorldPage\/{message}', osc_plugin_folder(__FILE__).'helloWorldPage.php');<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Link to our new route<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s create a href link in the footer of the page to our new route.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To do that we register a hook to run a function that will print our link. In order to get the actual&nbsp;<strong>url<\/strong>&nbsp;of our route we use the function&nbsp;<strong>osc_route_url()<\/strong>. To that we can also pass an array of values so here we decide what our message variable should be.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">function dliTest_footer() {\n  $pageUrl = osc_route_url('helloWorldPage', array('message' => 'Hello World!'));\n  echo '&lt;a href=\"'. echo $pageUrl .'\">Go to hello world!&lt;\/a>';\n} \nosc_add_hook('footer', 'dliTest_footer');<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Display our message<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If you refresh you site now you should see a link in your footer. But clicking it won\u2019t quite take us where we want yet, we first have to create our&nbsp;<strong>helloWorldPage.php<\/strong>&nbsp;file. Save it in the same folder as your&nbsp;<strong>index.php&nbsp;<\/strong>file. Here we extract the&nbsp;<strong>message<\/strong>&nbsp;parameter sent using the&nbsp;<strong>Params<\/strong>&nbsp;object and echo it.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\n  $message = Params::getParam('message');\n?>\n\n&lt;h3>&lt;?php echo $message?>&lt;\/h3><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now you will be able to click the link and be taken to the page showing your message.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Complete listing<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>index.php<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/*\nPlugin Name: dliTest\nPlugin URI: http:\/\/www.foobar.org\/\nDescription: A small test plugin\nVersion: 1.0.0\nAuthor: Daniel Liljeberg\nAuthor URI: http:\/\/www.danieliljebergorg\/\nShort Name: dliTest\nPlugin update URI: dli-test\nSupport URI: http:\/\/support.foobar.org\n*\/\n\n\/\/ Plugin functions\nfunction dliTest_install() {\n}\n\nfunction dliTest_uninstall() {\n}\n\nfunction dliTest_footer() {\n  $pageUrl = osc_route_url('helloWorldPage', array('message' => 'Hello World!'));\n  echo '&lt;a href=\"'. echo $pageUrl .'\">Go to hello world!&lt;\/a>';\n} \nosc_add_hook('footer', 'dliTest_footer');\n\/\/ Register routes \nosc_add_route('helloWorldPage', 'hellowWorldPage\/([a-zA-Z]+), 'helloWorldPage\/{message}', osc_plugin_folder(__FILE__).'helloWorldPage.php'); \n\n\/\/ Register hooks \nosc_register_plugin(osc_plugin_path(__FILE__), 'dliTest_install'); \nosc_add_hook(osc_plugin_path(__FILE__).\"_uninstall\", 'dliTest_uninstall');<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>helloWorldPage.php<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\n  $message = Params::getParam('message');\n?>\n\n&lt;h3>&lt;?php echo $message?>&lt;\/h3><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Closing thoughts<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This was a very simple plugin but the basic is the same even for larger plugins. You will end up with more hooks, more files and more routes. But this is what almost every plugin looks like. But keeping it all neat and easy for others to comprehend becomes quite hard when the plugins grow. We will look into this problem and how we can solve it in the next post.<\/p>\n\t\t\t<input type=\"hidden\" id=\"wplinkpress-user-email\" value=\"\" \/>\n<input type=\"hidden\" id=\"wplinkpress-authorize-url\" value=\"https:\/\/www.linkedin.com\/oauth\/v2\/authorization?response_type=code&client_id=77uzug7iq2dnd2&redirect_uri=https%3A%2F%2Fdaniel.liljeberg.io%2Fauthorize-linkedin%2F&state=https%3A%2F%2Fdaniel.liljeberg.io%2Fsv%2Fwp-json%2Fwp%2Fv2%2Fposts%2F37&scope=r_liteprofile%20r_emailaddress%20w_member_social\" \/>\n<input type=\"hidden\" id=\"wplinkpress-post-id\" value=\"37\" \/>\n<div class=\"ui wplinkpress comments\">\n<h3 class=\"ui dividing header\">Comments<\/h3>\n<form id=\"add-wplinkpress-comment\" method=\"POST\"> \n<div class=\"comment add-comment\">\n\t<a class=\"avatar\"><img src=\"https:\/\/daniel.liljeberg.io\/wp-content\/plugins\/wplinkpress\/assets\/media\/non-user-icon.jpg\" \/><\/a>\n\t<div class=\"content\">\n\t<textarea id=\"wplinkpress-comment-text-0\" class=\"wplinkpress-comment-text\" style=\"width:100%;\" placeholder=\"Add a comment...\"><\/textarea>\n\t<div class=\"bottom-layer\">\n\t\t<div class=\"comment-atts\" style=\"float:left;\">\n\t\t\t\t<div class=\"feed-share\">\n\t\t<label class=\"switch tips\">\n\t\t\t<input type=\"checkbox\" id=\"toggle-linkedin-feed\" >\n        \t<span class=\"slider round\"><\/span>\n\t\t<\/label>\n\t\t<span>Share on activity feed<\/span>\n\t\t<\/div>\n\t\t<\/div>\n\t<div class=\"wplinkpress_buttons\">\n\t\t<button id=\"authorize_comment_0\" class=\"authorize_comment\" disabled=\"disabled\">Post with LinkedIn<\/button>\n\t\t<\/div>\n\t<\/div>\n\t<\/div>\n<\/div>\n<\/form>\n<h3 class=\"ui dividing header\"><span class=\"wplinkpress-brand\">Powered by WP LinkPress<\/span><\/h3>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>As described in&nbsp;my earlier post, Osclass is a free, open-source, web application written in PHP for classified ads. One of the strong sides of it is that you have the options to create and install custom plugins to extend and alter the behavior of the application. There is an integrated market where existing plugins can&hellip;&nbsp;<a href=\"https:\/\/daniel.liljeberg.io\/sv\/2015\/04\/12\/how-to-develop-plugins-for-osclass\/\" rel=\"bookmark\">Read More &raquo;<span class=\"screen-reader-text\">How to develop Plugins for Osclass<\/span><\/a><\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","neve_meta_reading_time":"","footnotes":""},"categories":[2],"tags":[],"class_list":["post-37","post","type-post","status-publish","format-standard","hentry","category-osclass"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>How to develop Plugins for Osclass - Daniel Liljeberg<\/title>\n<meta name=\"description\" content=\"Osclass shares a lot of DNA with Wordpress. Here is how you build your own plugins for it.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/daniel.liljeberg.io\/sv\/2015\/04\/12\/how-to-develop-plugins-for-osclass\/\" \/>\n<meta property=\"og:locale\" content=\"sv_SE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to develop Plugins for Osclass - Daniel Liljeberg\" \/>\n<meta property=\"og:description\" content=\"Osclass shares a lot of DNA with Wordpress. Here is how you build your own plugins for it.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/daniel.liljeberg.io\/sv\/2015\/04\/12\/how-to-develop-plugins-for-osclass\/\" \/>\n<meta property=\"og:site_name\" content=\"Daniel Liljeberg\" \/>\n<meta property=\"article:published_time\" content=\"2015-04-12T16:21:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-04-01T20:02:08+00:00\" \/>\n<meta name=\"author\" content=\"Daniel Liljeberg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Skriven av\" \/>\n\t<meta name=\"twitter:data1\" content=\"Daniel Liljeberg\" \/>\n\t<meta name=\"twitter:label2\" content=\"Ber\u00e4knad l\u00e4stid\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minuter\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/2015\\\/04\\\/12\\\/how-to-develop-plugins-for-osclass\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/2015\\\/04\\\/12\\\/how-to-develop-plugins-for-osclass\\\/\"},\"author\":{\"name\":\"Daniel Liljeberg\",\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/#\\\/schema\\\/person\\\/e2c3fe10971c37cff2669f5688834cd7\"},\"headline\":\"How to develop Plugins for Osclass\",\"datePublished\":\"2015-04-12T16:21:00+00:00\",\"dateModified\":\"2021-04-01T20:02:08+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/2015\\\/04\\\/12\\\/how-to-develop-plugins-for-osclass\\\/\"},\"wordCount\":1752,\"publisher\":{\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/#\\\/schema\\\/person\\\/e2c3fe10971c37cff2669f5688834cd7\"},\"articleSection\":[\"Osclass\"],\"inLanguage\":\"sv-SE\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/2015\\\/04\\\/12\\\/how-to-develop-plugins-for-osclass\\\/\",\"url\":\"https:\\\/\\\/daniel.liljeberg.io\\\/2015\\\/04\\\/12\\\/how-to-develop-plugins-for-osclass\\\/\",\"name\":\"How to develop Plugins for Osclass - Daniel Liljeberg\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/#website\"},\"datePublished\":\"2015-04-12T16:21:00+00:00\",\"dateModified\":\"2021-04-01T20:02:08+00:00\",\"description\":\"Osclass shares a lot of DNA with Wordpress. Here is how you build your own plugins for it.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/2015\\\/04\\\/12\\\/how-to-develop-plugins-for-osclass\\\/#breadcrumb\"},\"inLanguage\":\"sv-SE\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/daniel.liljeberg.io\\\/2015\\\/04\\\/12\\\/how-to-develop-plugins-for-osclass\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/2015\\\/04\\\/12\\\/how-to-develop-plugins-for-osclass\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/daniel.liljeberg.io\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to develop Plugins for Osclass\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/#website\",\"url\":\"https:\\\/\\\/daniel.liljeberg.io\\\/\",\"name\":\"Daniel Liljeberg\",\"description\":\"The is no place like 127.0.0.1\",\"publisher\":{\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/#\\\/schema\\\/person\\\/e2c3fe10971c37cff2669f5688834cd7\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/daniel.liljeberg.io\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"sv-SE\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/#\\\/schema\\\/person\\\/e2c3fe10971c37cff2669f5688834cd7\",\"name\":\"Daniel Liljeberg\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"sv-SE\",\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/DanielLiljeberg.png\",\"url\":\"https:\\\/\\\/daniel.liljeberg.io\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/DanielLiljeberg.png\",\"contentUrl\":\"https:\\\/\\\/daniel.liljeberg.io\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/DanielLiljeberg.png\",\"width\":424,\"height\":440,\"caption\":\"Daniel Liljeberg\"},\"logo\":{\"@id\":\"https:\\\/\\\/daniel.liljeberg.io\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/DanielLiljeberg.png\"},\"description\":\"Agile practitioner and advocate. Strong believer in the future of agile organizations, businesses and teams. Got my first computer, a C64, at age 7 and computers has been part of my life since then. Working professionally with development since the early 2000\u2019s in a vast array of technologies and roles. Social, easy going, fun loving guy with an appetite for new challenges and new knowledge who has been \u201cthere\u201d and done \u201cthat\u201d. That\u2019s a good way to sum it all up. Married and father of three kids. All true blessings ;)\",\"sameAs\":[\"https:\\\/\\\/daniel.liljeberg.io\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/danielliljeberg\\\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How to develop Plugins for Osclass - Daniel Liljeberg","description":"Osclass shares a lot of DNA with Wordpress. Here is how you build your own plugins for it.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/daniel.liljeberg.io\/sv\/2015\/04\/12\/how-to-develop-plugins-for-osclass\/","og_locale":"sv_SE","og_type":"article","og_title":"How to develop Plugins for Osclass - Daniel Liljeberg","og_description":"Osclass shares a lot of DNA with Wordpress. Here is how you build your own plugins for it.","og_url":"https:\/\/daniel.liljeberg.io\/sv\/2015\/04\/12\/how-to-develop-plugins-for-osclass\/","og_site_name":"Daniel Liljeberg","article_published_time":"2015-04-12T16:21:00+00:00","article_modified_time":"2021-04-01T20:02:08+00:00","author":"Daniel Liljeberg","twitter_card":"summary_large_image","twitter_misc":{"Skriven av":"Daniel Liljeberg","Ber\u00e4knad l\u00e4stid":"11 minuter"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/daniel.liljeberg.io\/2015\/04\/12\/how-to-develop-plugins-for-osclass\/#article","isPartOf":{"@id":"https:\/\/daniel.liljeberg.io\/2015\/04\/12\/how-to-develop-plugins-for-osclass\/"},"author":{"name":"Daniel Liljeberg","@id":"https:\/\/daniel.liljeberg.io\/#\/schema\/person\/e2c3fe10971c37cff2669f5688834cd7"},"headline":"How to develop Plugins for Osclass","datePublished":"2015-04-12T16:21:00+00:00","dateModified":"2021-04-01T20:02:08+00:00","mainEntityOfPage":{"@id":"https:\/\/daniel.liljeberg.io\/2015\/04\/12\/how-to-develop-plugins-for-osclass\/"},"wordCount":1752,"publisher":{"@id":"https:\/\/daniel.liljeberg.io\/#\/schema\/person\/e2c3fe10971c37cff2669f5688834cd7"},"articleSection":["Osclass"],"inLanguage":"sv-SE"},{"@type":"WebPage","@id":"https:\/\/daniel.liljeberg.io\/2015\/04\/12\/how-to-develop-plugins-for-osclass\/","url":"https:\/\/daniel.liljeberg.io\/2015\/04\/12\/how-to-develop-plugins-for-osclass\/","name":"How to develop Plugins for Osclass - Daniel Liljeberg","isPartOf":{"@id":"https:\/\/daniel.liljeberg.io\/#website"},"datePublished":"2015-04-12T16:21:00+00:00","dateModified":"2021-04-01T20:02:08+00:00","description":"Osclass shares a lot of DNA with Wordpress. Here is how you build your own plugins for it.","breadcrumb":{"@id":"https:\/\/daniel.liljeberg.io\/2015\/04\/12\/how-to-develop-plugins-for-osclass\/#breadcrumb"},"inLanguage":"sv-SE","potentialAction":[{"@type":"ReadAction","target":["https:\/\/daniel.liljeberg.io\/2015\/04\/12\/how-to-develop-plugins-for-osclass\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/daniel.liljeberg.io\/2015\/04\/12\/how-to-develop-plugins-for-osclass\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/daniel.liljeberg.io\/"},{"@type":"ListItem","position":2,"name":"How to develop Plugins for Osclass"}]},{"@type":"WebSite","@id":"https:\/\/daniel.liljeberg.io\/#website","url":"https:\/\/daniel.liljeberg.io\/","name":"Daniel Liljeberg","description":"The is no place like 127.0.0.1","publisher":{"@id":"https:\/\/daniel.liljeberg.io\/#\/schema\/person\/e2c3fe10971c37cff2669f5688834cd7"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/daniel.liljeberg.io\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"sv-SE"},{"@type":["Person","Organization"],"@id":"https:\/\/daniel.liljeberg.io\/#\/schema\/person\/e2c3fe10971c37cff2669f5688834cd7","name":"Daniel Liljeberg","image":{"@type":"ImageObject","inLanguage":"sv-SE","@id":"https:\/\/daniel.liljeberg.io\/wp-content\/uploads\/2020\/12\/DanielLiljeberg.png","url":"https:\/\/daniel.liljeberg.io\/wp-content\/uploads\/2020\/12\/DanielLiljeberg.png","contentUrl":"https:\/\/daniel.liljeberg.io\/wp-content\/uploads\/2020\/12\/DanielLiljeberg.png","width":424,"height":440,"caption":"Daniel Liljeberg"},"logo":{"@id":"https:\/\/daniel.liljeberg.io\/wp-content\/uploads\/2020\/12\/DanielLiljeberg.png"},"description":"Agile practitioner and advocate. Strong believer in the future of agile organizations, businesses and teams. Got my first computer, a C64, at age 7 and computers has been part of my life since then. Working professionally with development since the early 2000\u2019s in a vast array of technologies and roles. Social, easy going, fun loving guy with an appetite for new challenges and new knowledge who has been \u201cthere\u201d and done \u201cthat\u201d. That\u2019s a good way to sum it all up. Married and father of three kids. All true blessings ;)","sameAs":["https:\/\/daniel.liljeberg.io","https:\/\/www.linkedin.com\/in\/danielliljeberg\/"]}]}},"_links":{"self":[{"href":"https:\/\/daniel.liljeberg.io\/sv\/wp-json\/wp\/v2\/posts\/37","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/daniel.liljeberg.io\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/daniel.liljeberg.io\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/daniel.liljeberg.io\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/daniel.liljeberg.io\/sv\/wp-json\/wp\/v2\/comments?post=37"}],"version-history":[{"count":4,"href":"https:\/\/daniel.liljeberg.io\/sv\/wp-json\/wp\/v2\/posts\/37\/revisions"}],"predecessor-version":[{"id":48,"href":"https:\/\/daniel.liljeberg.io\/sv\/wp-json\/wp\/v2\/posts\/37\/revisions\/48"}],"wp:attachment":[{"href":"https:\/\/daniel.liljeberg.io\/sv\/wp-json\/wp\/v2\/media?parent=37"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/daniel.liljeberg.io\/sv\/wp-json\/wp\/v2\/categories?post=37"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/daniel.liljeberg.io\/sv\/wp-json\/wp\/v2\/tags?post=37"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}