| 741 | Add the following function to the '''MeBlggModule''' class: |
| 742 | |
| 743 | |
| 744 | {{{ |
| 745 | function actionView ($iEntryId) { |
| 746 | |
| 747 | $aEntry = $this->_oDb->getEntryById ((int)$iEntryId); |
| 748 | if (!$aEntry) { // check if entry exists |
| 749 | $this->_oTemplate->displayPageNotFound (); |
| 750 | return; |
| 751 | } |
| 752 | |
| 753 | $this->_oTemplate->pageStart(); // all the code below will be wrapped by the user design |
| 754 | |
| 755 | $aVars = array ( |
| 756 | 'title' => $aEntry['title'], |
| 757 | 'text' => $aEntry['text'], |
| 758 | 'author' => getNickName($aEntry['author_id']), |
| 759 | 'added' => defineTimeInterval($aEntry['added']), |
| 760 | ); |
| 761 | echo $this->_oTemplate->parseHtmlByName('view', $aVars); // display post |
| 762 | |
| 763 | $this->_oTemplate->pageCode($aEntry['title'], true); // output is completed, display all output above data wrapped by user design |
| 764 | } |
| 765 | }}} |
| 766 | |
| 767 | This is the first time where our function accepts any parameters: |
| 768 | |
| 769 | * '''$iEntryId''' function parameter will be passed when we call the following URL: '''http://www.your-site.com/your-path/m/bloggie/view/15''', in this case '''$iEntryId''' will be equal to "'''15'''". |
| 770 | * '''getNickName''' is the system function which returns the user name by user id. |
| 771 | * '''defineTimeInterval''' function generates a human readable representation of the unix timestamp date/time. |
| 772 | * '''displayPageNotFound''' displays a message like "Page Not Found" along with HTTP 404 headers. |
| 773 | * '''getEntryById''' is the database function which is created below. |
| 774 | |
| 775 | Add the following method to the '''MeBlggDb''' class: |
| 776 | |
| 777 | {{{ |
| 778 | function getEntryById ($iEntryId) { |
| 779 | return $this->getRow("SELECT * FROM `" . $this->_sPrefix . "posts` WHERE `id` = '$iEntryId'"); |
| 780 | } |
| 781 | }}} |
| 782 | |
| 783 | We have already described database functions, and there is nothing to clarify. The only thing is that it is good practice to use the '''$this->_sPrefix''' variable as the database prefix for the module's tables. |
| 784 | |
| 785 | The last thing is the '''bloggie/templates/base/view.html''' file: |
| 786 | |
| 787 | {{{ |
| 788 | <div> |
| 789 | <h1>__title__</h1> |
| 790 | <p>__text__</p> |
| 791 | <p style="text-align:right; font-style:italic;"><bx_text:_me_blgg_posted_by /> __author__ (__added__)</p> |
| 792 | </div> |
| 793 | }}} |
| 794 | |
| 795 | This file looks extremely simple. |
| 796 | |
| 797 | Try to add some Bloggie post and you will be redirected to the view post page. |
| 798 | |
| 799 | Now the only page we are missing is the page with the posts list. |
| 800 | |
| 801 | |
| 802 | == 4.4. Creating Bloggie homepage with a posts list. == |
| 803 | |
| 804 | Change the '''actionHome''' function the following way: |
| 805 | |
| 806 | {{{ |
| 807 | function actionHome () { |
| 808 | $this->_oTemplate->pageStart(); // all the code below will be wrapped by the user design |
| 809 | |
| 810 | $aPosts = $this->_oDb->getAllPosts (getParam('me_blgg_max_posts_to_show')); // get all posts from database |
| 811 | foreach ($aPosts as $sKey => $aRow) { // add human readable values to the resulted array |
| 812 | $aPosts[$sKey]['url'] = BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'view/' . $aRow['id']; |
| 813 | $aPosts[$sKey]['added'] = defineTimeInterval($aRow['added']); |
| 814 | $aPosts[$sKey]['author'] = getNickName($aRow['author_id']); |
| 815 | } |
| 816 | $aVars = array ( // define template variables |
| 817 | 'bx_repeat:posts' => $aPosts, |
| 818 | ); |
| 819 | echo $this->_oTemplate->parseHtmlByName('main', $aVars); // output posts list |
| 820 | |
| 821 | $this->_oTemplate->pageCode(_t('_me_blgg'), true); // output is completed, display all output above data wrapped by user design |
| 822 | } |
| 823 | }}} |
| 824 | |
| 825 | then place the following code into the '''bloggie/templates/base/main.html''' file: |
| 826 | |
| 827 | {{{ |
| 828 | <bx_repeat:posts> |
| 829 | <h2> |
| 830 | <a href="__url__">__title__</a> |
| 831 | </h2> |
| 832 | <p>__text__</p> |
| 833 | <p style="text-align:right; font-style:italic;"><bx_text:_me_blgg_posted_by /> __author__ (__added__)</p> |
| 834 | <hr /> |
| 835 | </bx_repeat:posts> |
| 836 | }}} |
| 837 | |
| 838 | And we have added a new database class method: |
| 839 | |
| 840 | {{{ |
| 841 | function getAllPosts ($iLimit) { |
| 842 | return $this->getAll("SELECT *, LEFT(`text`, 256) AS `text` FROM `" . $this->_sPrefix . "posts` ORDER BY `added` DESC LIMIT $iLimit"); |
| 843 | } |
| 844 | }}} |
| 845 | |
| 846 | |
| 847 | We have used the new template construction '''bx_repeat:posts''' here. This allows us to iterate through an array of similar data, Blog posts are the data to iterate through, in this case. |
| 848 | Also, we used a new config class method - '''getBaseUri ''' It returns '''modules/?r=bloggie/''' or '''m/bloggie/''' depending on the permalinks settings. It is mandatory to generate all links this way, so the links will work when '''mod_rewrite''' is disabled. |
| 849 | |
| 850 | Almost everything is done here. The last thing we will add to Bloggie module will be edit post page. |
| 851 | |
| 852 | |
| 853 | == 4.5. Edit the post page. == |
| 854 | |
| 855 | Add the following method to the '''MeBlggModule''' class: |
| 856 | |
| 857 | {{{ |
| 858 | function actionEdit ($iEntryId) { |
| 859 | |
| 860 | $aEntry = $this->_oDb->getEntryById ((int)$iEntryId); |
| 861 | if (!$aEntry) { // check if entry exists |
| 862 | $this->_oTemplate->displayPageNotFound (); |
| 863 | return; |
| 864 | } |
| 865 | |
| 866 | if ((!$GLOBALS['logged']['member'] && !$GLOBALS['logged']['admin']) || $aEntry['author_id'] != $_COOKIE['memberID']) { // check access to the page |
| 867 | $this->_oTemplate->displayAccessDenied (); |
| 868 | return; |
| 869 | } |
| 870 | |
| 871 | $this->_oTemplate->pageStart(); // all the code below will be wrapped by the user design |
| 872 | |
| 873 | bx_import ('BxTemplFormView'); // import forms class |
| 874 | |
| 875 | $oForm = new BxTemplFormView ($this->aForm); // create forms class |
| 876 | |
| 877 | $oForm->initChecker($aEntry); // init form checker |
| 878 | |
| 879 | if ($oForm->isSubmittedAndValid ()) { // if form is submitted and there is no form errors were found, save form data |
| 880 | |
| 881 | $iRes = $oForm->update ($iEntryId); // update data in database |
| 882 | |
| 883 | if ($iRes) { // if post was successfully added |
| 884 | $sRedirectUrl = BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'view/' . $iEntryId; |
| 885 | header ('Location:' . $sRedirectUrl); // redirect to updated post view page |
| 886 | exit; |
| 887 | } else { |
| 888 | MsgBox(_t('_Error Occured')); // if error occured display error message |
| 889 | } |
| 890 | |
| 891 | } else { |
| 892 | |
| 893 | echo $oForm->getCode (); // display form, if the form is not submitted or data is invalid |
| 894 | |
| 895 | } |
| 896 | |
| 897 | $this->_oTemplate->pageCode(_t('_me_blgg_page_title_edit'), true); // output is completed, display all output above data wrapped by user design |
| 898 | } |
| 899 | }}} |
| 900 | |
| 901 | This function is pretty similar to the actionAdd method - with the following differences: |
| 902 | |
| 903 | * there is additional access checking to allow only the post owner to edit it |
| 904 | * '''initChecker''' receives '''$aEntry''' as a parameter to fill our form with values, since it is an edit form |
| 905 | * instead of '''save''' we called the '''update''' form function with the post's primary id number, to indicate the post to update |
| 906 | |
| 907 | The last thing to do is to update the view post page and add an edit link to it. The edit post link will be added near the post title. To achieve this, we need to modify the '''actionView''' method in the following way: |
| 908 | |
| 909 | {{{ |
| 910 | function actionView ($iEntryId) { |
| 911 | |
| 912 | $aEntry = $this->_oDb->getEntryById ((int)$iEntryId); |
| 913 | |
| 914 | if (!$aEntry) { // check if entry exists |
| 915 | $this->_oTemplate->displayPageNotFound (); |
| 916 | return; |
| 917 | } |
| 918 | |
| 919 | $this->_oTemplate->pageStart(); // all the code below will be wrapped by the user design |
| 920 | |
| 921 | $aVars = array ( |
| 922 | 'title' => $aEntry['title'], |
| 923 | 'text' => $aEntry['text'], |
| 924 | 'author' => getNickName($aEntry['author_id']), |
| 925 | 'added' => defineTimeInterval($aEntry['added']), |
| 926 | 'bx_if:edit' => array( |
| 927 | 'condition' => ($GLOBALS['logged']['member'] || $GLOBALS['logged']['admin']) && $aEntry['author_id'] == $_COOKIE['memberID'], |
| 928 | 'content' => array( |
| 929 | 'edit_url' => BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'edit/' . $aEntry['id'], |
| 930 | ), |
| 931 | ), |
| 932 | ); |
| 933 | echo $this->_oTemplate->parseHtmlByName('view', $aVars); // display post |
| 934 | |
| 935 | $this->_oTemplate->pageCode($aEntry['title'], true); // output is completed, display all output above data wrapped by user design |
| 936 | } |
| 937 | |
| 938 | }}} |
| 939 | |
| 940 | and place the code below into the '''bloggie/templates/base/view.html''' file: |
| 941 | |
| 942 | {{{ |
| 943 | <div> |
| 944 | <h1> |
| 945 | __title__ |
| 946 | <bx_if:edit> |
| 947 | <a href="__edit_url__"><bx_text:_me_blgg_edit /></a> |
| 948 | </bx_if:edit> |
| 949 | </h1> |
| 950 | <p>__text__</p> |
| 951 | <p style="text-align:right; font-style:italic;"><bx_text:_me_blgg_posted_by /> __author__ (__added__)</p> |
| 952 | </div> |
| 953 | }}} |
| 954 | |
| 955 | We have passed a new variable to the template with the edit post link, but is has a condition that only the owner can edit the post. |
| 956 | |
| 957 | Try this new functionality by editing already created posts. |
| 958 | |
| 959 | You can download the resulting module to compare with your own, here: (TODO:bloggie4.zip). |
| 960 | |
| 961 | Congratulations! The first Dolphin 7 module is now completed. I hope that you are full of ideas on how to extend this module for your own needs or create a new one from scratch. |
| 962 | |
| 963 | |
| 964 | == 5. What to do next. == |
| 965 | |
| 966 | There are many resources where you can get some Dolphin knowledge and share your experience: |
| 967 | |
| 968 | * [http://www.boonex.com/unity/ BoonEx Unity Forums] - report bugs, ask for the help and help others if you see that you have an answer. |
| 969 | * [http://www.boonex.com/unity/blog/home BoonEx Blog] - find helpful blog posts of others and make your post if you think you have something to share about your Dolphin experience. |
| 970 | * [http://www.boonex.com/unity/extensions/home BoonEx Market] - download free and paid modules for Dolphin or post your own mods. |
| 971 | * [http://www.boonex.com/trac/dolphin/roadmap BoonEx Tickets System] - check the current Dolphin development stage or get latest source code. |
| 972 | * [http://www.boonex.com/trac/dolphin/wiki/DolphinDocs BoonEx Wiki] - Dolphin documentation. |
| 973 | * [http://www.boonex.com/agents/ BoonEx Agents] - get support from your personal BoonEx agent |
| 974 | |
| 975 | |
| 976 | You probably have many questions or are willing to share your new module or experience with others after reading this post, so use the links above to do it in the right place. |
| 977 | |