1
June
2021
Tutorial

Build a CMS for Your Company in Under an Hour

0
 minutes

by Adeyinka Adegbenro

A content management system (CMS) is software used to manage the creation and editing of content, usually formatted articles containing images and videos. A very popular example of a CMS is the WordPress CMS. CMSs are very important tools for managing content because they make it easy to create, update, and delete data without any coding knowledge.

Appsmith is an open-source framework that helps developers build dashboards, workflows, pages, and CRUD apps very quickly. Appsmith allows you to build tools with little or no code, with the ability to connect to APIs or databases such as MongoDB, PostGreSQL, or MYSQL, as the case may be. You also get access to charts, widgets, and other customization tools for building a UI. Appsmith has more flexibility than off-the-shelf options, and it’s fast to build and easy to maintain.

In this article, you will learn how to set up Appsmith locally, create a new application, connect an API to it, and build a content management system using widgets and pages.

Setting Up the Application and Database

This section will focus on how to create a CMS as an Appsmith application, as well as how to set up and connect a SQL database for use in Appsmith.

Create an Appsmith App

For the purpose of this tutorial, you’re going to create a local instance of Appsmith using Docker. Read Appsmith’s documentation to set this up for your operating system.

After going through those steps, visit http://localhost/ in your browser to see the local version of Appsmith. Create a local account to log in. Next, click the Create New button to create a new application and name it CMS. This takes you to an empty workspace with a sidebar. On the sidebar, you should see items such as Pages, API, and DB Queries.

Connect to a Database

To work with Appsmith, you need a data source. This can be in the form of an API or a database. Appsmith supports MongoDB, MySQL, and PostgreSQL among others.

In this tutorial, you’ll connect to a local PostgreSQL database. To create the data models required for the CMS, go into the PostgreSQL command line, and create the database:

CREATE DATABASE appsmith_cms;

Connect to the database and create a DB table called Author:

CREATE TABLE AUTHOR(
   AUTHOR_ID SERIAL PRIMARY KEY NOT NULL,
   NAME TEXT NOT NULL,
   PROFILE_PICTURE TEXT,
   ABOUT_ME TEXT,
   LINKEDIN TEXT,
   GITHUB TEXT
);

Create a table, Article:

CREATE TABLE ARTICLE(
   ARTICLE_ID SERIAL PRIMARY KEY NOT NULL,
   TITLE TEXT NOT NULL,
   SUBTITLE TEXT,
   CONTENT TEXT,
   IMAGE TEXT,
   AUTHOR_ID INTEGER NOT NULL REFERENCES AUTHOR(AUTHOR_ID),
   DATE_UPDATED DATE NOT NULL DEFAULT CURRENT_DATE
);

Create a table, Tag:

CREATE TABLE TAG (
    TAG_ID SERIAL PRIMARY KEY NOT NULL,
    NAME TEXT NOT NULL
);

Create a table, Article_Tag:

CREATE TABLE ARTICLE_TAG(
    ARTICLE_ID INTEGER REFERENCES ARTICLE(ARTICLE_ID),
    TAG_ID INTEGER REFERENCES TAG(TAG_ID),
    PRIMARY KEY (ARTICLE_ID, TAG_ID)
);

By now, you should have a standard database with the tables Author, Article, Tag, and Article_Tag on it. Next, insert some data into the database tables by running the following queries, so you can view it when you build your user interface:

INSERT into author (name, profile_picture, about_me, linkedin, github) VALUES ( 'Achebe', 'https://en.wikipedia.org/wiki/Chinua_Achebe', 'i am cool', 'https://www.linkedin.com/', 'https://github.com/');

INSERT into author (name, profile_picture, about_me, linkedin, github) VALUES ( 'Chimamanda', 'https://en.wikipedia.org/wiki/Chimamanda_Ngozi_Adichie', 'i am cool', 'https://www.linkedin.com/', 'https://github.com/');


INSERT INTO "article" ( "title", "subtitle", "content", "image", "author_id") VALUES
( 'Hello', 'hi', 'Hello world', 'img.me', '1');


INSERT INTO "tag" ("name") VALUES
('food');

INSERT INTO "tag" ("name") VALUES
('tech');

INSERT INTO "tag" ("name") VALUES
('fashion');

INSERT INTO "tag" ("name") VALUES
('beauty');

To connect to the appsmith_cms database from within Appsmith, go to the application sidebar. Click the plus icon near DB Queries, then click New Datasource, select PostgreSQL, and enter the connection details for your database.

Since you are on localhost, set the host address as host.docker.internal and the database name as appsmith_cms. Add your PostgreSQL username and password to the Authentication section and click Connect. Once connected, rename the new datasource as CMS.

Your App’s First Page: Create an Article

In this section, you’ll create the first UI view of your CMS application. It will be a form with several fields, for title, content, cover image, and a URL. These form fields will take in all the necessary data for creating an article.

On the sidebar, under Pages, a new page called Page1 already exists. Rename it as create_article_page.

Prepare the Data

Before building the form, prepare the queries necessary for creating an article.

Click the plus icon near DB Queries and click the New Query button near the CMS Datasource to create a new query. Rename it fetch_authors from the default name Query1. This will be useful in displaying all the available authors in your database. Paste the following code in the query box and run it:

SELECT * FROM author;

Create a new query called fetch_tags. This will be useful for displaying all available tags in your database. Paste the following code in the box and run it:

SELECT * FROM tag;

Create a new query called submit_article. This will be used to create a new article entry in the database.

INSERT INTO "article" ( "title", "subtitle", "content", "image", "author_id") 
VALUES
('{{create_article_form.data.title}}', 
'{{create_article_form.data.subtitle}}', 
'{{create_article_form.data.content}}', 
'{{create_article_form.data.cover_image}}', 
{{create_article_form.data.author}}
) returning "article_id"
;

Create a new query called create_article_tag. This will be used to create a new article_tag entry that associates a tag with an article.

INSERT INTO article_tag
  ("article_id", "tag_id")
VALUES
  (
    '{{submit_article.data[0].article_id}}', 
    '{{create_article_form.data.tags}}'
  );

Build the Page

Go to create_article_page > Widgets, and add a form to the page by clicking the plus icon. Drag and drop a Form widget to the page’s workspace. Click the settings gear to configure the form. Change the form name from form1 to create_article_form.

Next, let’s add a few fields along with labels.

To begin, add a Text widget and label it Title:, then drag the Input widget in front of it and change its name from input1 to title.

Below that, add a Text widget and label it Subtitle:, then drag the Input widget in front of it and change its name from input1 to subtitle.

Add a Text widget and label it Content:, then drag the Rich Text Editor widget in front of it and change its name from RichTextEditor1 to content. Delete the default text.

Add a Text widget and label it Cover Image:, then drag the Input widget in front of it and change its name from input1 to cover_image.

Add a Text widget and label it Author, then drag the Dropdown widget in front of it and change its name from Dropdown1 to author. In the options settings for this dropdown, add the following code:

{{
fetch_authors.data.map(
  (row)=>{

    return {label: row.name, value: row.author_id}
  }
)
}}

Add a Text widget and label it Tags:, then drag the Dropdown widget in front of it and change its name from Dropdown1 to tags. In the options settings for this dropdown, add the following code:

  {{
fetch_tags.data.map(
  (row)=>{

    return {label: row.name, value: row.tag_id}
  }
)
}}

Go to the onClick section of the Submit button’s settings, and select Execute a DB Query, choose the submit_article query, then in the onSuccess section, select Execute a DB Query > create_article_tag query. This creates an article entry in the database, and then creates the article_tag entry that links the tag and article together.

To test that it works, fill in the form with some test data and submit it. In the Article table in your database, you should see the new article row with data you just filled in.

The create_article_form

Your App’s Second Page: View Articles

Create a new page called all_articles_page. This page will be used to display all the articles available in the database.

Prepare the Query

Add a new query called fetch_articles and run it. This query will fetch all the articles in the database, as well the authors who wrote them.

SELECT art.*, aut.name as author FROM article art 
join author aut on aut.author_id = art.author_id;

Build the UI

On the all_articles_page, drag a table widget to the page and rename it articles_table. In the Table Data section of the table settings, set the value to {{fetch_articles.data}}. This will use data from the fetch_articles query defined above. By now, the table should be populated with a list of all the articles. The table automatically comes with search, pagination, and filter features.

Next, add a new column to the table and call it View. In the settings for View, set the Column Type as a button, label it View, and set the value for onClick as {{navigateTo('view_article_page', {"key": currentRow.article_id})}} after setting it to JS mode.

This means that when View is clicked, a user will go to the view_article_page.

Create a new page and name it view_article_page. Create a new query, get_article, and fill it as:

select art.*, tag.name as tag_name, tag.tag_id, auth.name as author from article art join
author auth on auth.author_id = art.author_id
left join article_tag at on at.article_id = art.article_id
left join tag on tag.tag_id = at.tag_id
where art.article_id = {{ appsmith.URL.queryParams.key }};
The all_articles_page

Go back to the view_article_page and add the following widgets and settings:

  1. Add a Text widget for the title and set the value of Text to {{get_article.data[0].title}}.
  2. Add another Text widget for the subtitle and set the value of Text to {{get_article.data[0].subtitle}}.
  3. Add an Image widget for the cover image and set the value of Image to {{get_article.data[0].image}}.
  4. Add a Text widget for the article content and set the value of Text to {{get_article.data[0].content}}.
  5. Add a Text widget for the article’s author and set the value of Text to Written By {{get_article.data[0].author}}
  6. To test that the configuration works, go to the all_articles_page and click View on any of the rows. This should take you to the view_articles_page with the actual article loaded.
The view_article_page

Your App’s Third Page: Edit an Article

On the all_articles_page, add a new column to the table. Then add a button called Edit to the column. In the settings for Edit, set the onClick section to JS and add {{navigateTo('edit_article_page',{"key": currentRow.article_id})}} as its value.

The new Edit button

Create a new page and name it edit_article_page. On this page, you’ll add a form to edit existing articles. You'll also make sure that the form is prefilled with the details of the article you want to edit.

Prepare the Data

Go to view_article_page > DB Queries > get_article and copy the get_article query to edit_article_page.

Go to the queries under the create_articles_page, click the three dots near fetch_authors, and select Copy to Page and then edit_article_page. Copy the query fetch_tags to the edit_article_page as well. Under the edit_article_page, you should see all the copied queries. Make sure that the getArticlesCopy ends with { appsmith.URL.queryParams.key }}; instead of {{ }};.

Create a new query edit_article_query and add:

 update article 
SET title = '{{edit_article_form.data.title}}',
    subtitle = '{{edit_article_form.data.subtitle}}',
    content = '{{edit_article_form.data.content}}',
    image = '{{edit_article_form.data.cover_image}}',
    author_id = {{edit_article_form.data.author}}
  WHERE article_id = {{ get_articleCopy.data[0].article_id }};

Create a new query, new_article_tag_query, and add:

INSERT INTO article_tag
  (article_id, tag_id)
VALUES
  (
    '{{ get_articleCopy.data[0].article_id }}',
    '{{ edit_article_form.data.tag }}'
  );

Create a new query, delete_old_article_tags, and add:

DELETE FROM article_tag 
WHERE article_id = {{get_articleCopy.data[0].article_id}};

Build the Page

To build the edit_article_page page, add a Form widget to the page, click the settings gear, and rename the form edit_article_form. Change the form label to Edit an Article.

Add six text widgets to the form and label them Title, Subtitle, Content, Cover Image, Author, and Tag respectively, just like you did on the create_article_page.

Drag the Input widget in front of Title and Subtitle and change their names from input1 to title and subtitle respectively. Open the title widget and set default text as {{get_articleCopy.data[0].title}}. Also set default text for Subtitle as {{get_articleCopy.data[0].subtitle}}.

Drag the Rich Text Editor widget in front of the Content label and change its name from input1 to content. Set the widget's default text as {{get_articleCopy.data[0].content}}.

Drag the Input widget in front of the Cover Image label. Rename the widget cover_image. Set the default text as {{get_articleCopy.data[0].image}}.

Drag a dropdown widget in front of both the Author and Tag labels. For Author, change its name from Dropdown1 to author and set the default text as the following:

{{
  fetch_authorsCopy.data.map(
  (row)=>{

    return {label: row.name, value: row.author_id.toString()}
  }
  )
}}

And the Default Option as {{get_articleCopy.data[0].author_id}}.

For the Tag field, change its name from Dropdown2 to tag and set the options as:

  {{
    fetch_tagsCopy.data.map(
    (row)=>{

      return {label: row.name, value: row.tag_id.toString()}
    }
    )
  }}

And the Default Option as {{get_articleCopy.data[0].tag_id}}.

In the Submit button's settings, go to the onClick section and click JS. Set the value as:

 {{edit_article_query.run(() => delete_old_article_tags.run(() => new_article_tag_query.run(() => get_articleCopy.run()) ), () => {})}}

To test that the configuration works, go to the all_articles_page and click the Edit button on one of the rows. This should bring you to the edit_article_page, with the form prefilled with the selected row's data.

From here you can edit the article and then submit. Confirm that the article got edited successfully from the all_articles_page by looking up the row to see if the data changed.

The edit_article_form

Your App’s Fourth Page: Manage Tags and Authors

Create a new page called authors_and_tags_page. On this page, you'll be able to view all the Authors and Tags. You'll also add the ability to remove and add tags.

Prepare the Queries

Go to the create_article_page > DB Queries and copy fetch_authors and fetch_tag to authors_and_tags_page.

Create a new query, create_tag_query, and paste in the following:

INSERT INTO tag
  (name)
VALUES
  (
    '{{create_tag_modal.data.tag_name}}'
  );

Create a new query, delete_article_tag_query, and paste in the following:

INSERT INTO tag
 DELETE FROM article_tag 
WHERE tag_id = {{tags_table.selectedRow.tag_id}};

Create another query, delete_tag, and add the following code:

DELETE FROM tag WHERE tag_id= {{tags_table.selectedRow.tag_id}}

Build the Page UI

To start building the page UI, add a text widget and name it Authors. Underneath, add a table widget and rename it author_table. Set the Table Data as {{fetch_authorsCopy.data}}. Reload the page.

Add a new column called Action. Go to Action's settings, set its column type as Button, and label the button as View. In the onClick section, set it as JS, and the value as {{showModal('view_author_modal')}}.

You just created a button on the table called View. When this button is clicked, you want it to open a modal called view_author_modal.

The Authors table

To create view_author_modal, drag a Modal widget to the page and rename it view_author_modal. Change the Modal Title text to View Author, set the Modal Type as a Form Modal, and delete the buttons in the modal. Dismiss the modal and click one of the View buttons on the Authors table. This should open up the modal.

Now add a Text widget and set the Text value to {{author_table.selectedRow.name}} in the settings.

Add an Image widget and give it an Image value of {{author_table.selectedRow.profile_picture}}.

Add a Text widget and label it LinkedIn:. In front of it, add another Text widget and give it a Text value of {{author_table.selectedRow.linkedin}}.

Add a Text widget and label it GitHub:. In front of it, add another Text widget and give it a Text value of {{author_table.selectedRow.github}}.

At this point, you should see all of the Author's information rendered on the modal.

Screenshot of the view_article_modal

Next, you need to create a table to display all the tags. Start by adding a Text widget and labeling it Tags. Underneath, add a Table widget and rename it tags_table. Set the Table Data as {{fetch_tagsCopy.data}} and reload the page.

Add a new column called Action. Go to Action's settings, set its column type as Button, and label it as remove. Set the button to Red as well. In the onClick section, enable JS and paste the value as {{delete_article_tag_query.run(() => delete_tag.run(), () => {})}}.

You can test deleting a tag by clicking one of the remove buttons on the Tags table.

Add a Button widget in the bottom right corner underneath the Tags table and label it Add Tag. Next, in the button's onClick settings, click JS and paste the value {{navigateTo('create_tag_page','SAME_WINDOW')}}. Here you’ve configured the Add Tag button to open a new page called create_tag_page.

The Tags table

Create a new page called create_tag_page. When the Add Tag button is clicked, it should go to this new page.

Go to DB Queries and create a new query called create_tag_query. Paste in the following:

INSERT INTO tag
(name)
VALUES
(
  '{{create_tag_form.data.tag_name }}'
);

Go back to the create_tag_page, and drag a Form widget into the workspace. Rename it create_tag_form. Then inside the form, add a Text widget and label it Add Tag.

Underneath, add a Text widget and label it Name:. In front of it add an input widget and rename it tag_name.

Go to the onClick section of the Submit button settings and select Execute a DB Query. Choose the create_tag_query. In the onSuccess section, select Navigate to, and for Page Name enter authors_and_tags_page. This means you want to navigate to the Tags page once a new tag has been created.

Test creating a new tag and checking that it is present on the Tags table.

The create_tag_page

Conclusion

You've seen how easy and fast it is to build a content management system on Appsmith. You’ve connected to a database and built pages and made them interactive. You’ve experimented with how Appsmith’s widgets work, and you’ve learned to customize them for your purposes.

If you’re looking for a fast way to create a CMS or some other internal tool with minimal need for developer hours, consider building it with Appsmith.

Build a CMS for Your Company in Under an Hour

by Adeyinka Adegbenro

A content management system (CMS) is software used to manage the creation and editing of content, usually formatted articles containing images and videos. A very popular example of a CMS is the WordPress CMS. CMSs are very important tools for managing content because they make it easy to create, update, and delete data without any coding knowledge.

Appsmith is an open-source framework that helps developers build dashboards, workflows, pages, and CRUD apps very quickly. Appsmith allows you to build tools with little or no code, with the ability to connect to APIs or databases such as MongoDB, PostGreSQL, or MYSQL, as the case may be. You also get access to charts, widgets, and other customization tools for building a UI. Appsmith has more flexibility than off-the-shelf options, and it’s fast to build and easy to maintain.

In this article, you will learn how to set up Appsmith locally, create a new application, connect an API to it, and build a content management system using widgets and pages.

Setting Up the Application and Database

This section will focus on how to create a CMS as an Appsmith application, as well as how to set up and connect a SQL database for use in Appsmith.

Create an Appsmith App

For the purpose of this tutorial, you’re going to create a local instance of Appsmith using Docker. Read Appsmith’s documentation to set this up for your operating system.

After going through those steps, visit http://localhost/ in your browser to see the local version of Appsmith. Create a local account to log in. Next, click the Create New button to create a new application and name it CMS. This takes you to an empty workspace with a sidebar. On the sidebar, you should see items such as Pages, API, and DB Queries.

Connect to a Database

To work with Appsmith, you need a data source. This can be in the form of an API or a database. Appsmith supports MongoDB, MySQL, and PostgreSQL among others.

In this tutorial, you’ll connect to a local PostgreSQL database. To create the data models required for the CMS, go into the PostgreSQL command line, and create the database:

CREATE DATABASE appsmith_cms;

Connect to the database and create a DB table called Author:

CREATE TABLE AUTHOR(
   AUTHOR_ID SERIAL PRIMARY KEY NOT NULL,
   NAME TEXT NOT NULL,
   PROFILE_PICTURE TEXT,
   ABOUT_ME TEXT,
   LINKEDIN TEXT,
   GITHUB TEXT
);

Create a table, Article:

CREATE TABLE ARTICLE(
   ARTICLE_ID SERIAL PRIMARY KEY NOT NULL,
   TITLE TEXT NOT NULL,
   SUBTITLE TEXT,
   CONTENT TEXT,
   IMAGE TEXT,
   AUTHOR_ID INTEGER NOT NULL REFERENCES AUTHOR(AUTHOR_ID),
   DATE_UPDATED DATE NOT NULL DEFAULT CURRENT_DATE
);

Create a table, Tag:

CREATE TABLE TAG (
    TAG_ID SERIAL PRIMARY KEY NOT NULL,
    NAME TEXT NOT NULL
);

Create a table, Article_Tag:

CREATE TABLE ARTICLE_TAG(
    ARTICLE_ID INTEGER REFERENCES ARTICLE(ARTICLE_ID),
    TAG_ID INTEGER REFERENCES TAG(TAG_ID),
    PRIMARY KEY (ARTICLE_ID, TAG_ID)
);

By now, you should have a standard database with the tables Author, Article, Tag, and Article_Tag on it. Next, insert some data into the database tables by running the following queries, so you can view it when you build your user interface:

INSERT into author (name, profile_picture, about_me, linkedin, github) VALUES ( 'Achebe', 'https://en.wikipedia.org/wiki/Chinua_Achebe', 'i am cool', 'https://www.linkedin.com/', 'https://github.com/');

INSERT into author (name, profile_picture, about_me, linkedin, github) VALUES ( 'Chimamanda', 'https://en.wikipedia.org/wiki/Chimamanda_Ngozi_Adichie', 'i am cool', 'https://www.linkedin.com/', 'https://github.com/');


INSERT INTO "article" ( "title", "subtitle", "content", "image", "author_id") VALUES
( 'Hello', 'hi', 'Hello world', 'img.me', '1');


INSERT INTO "tag" ("name") VALUES
('food');

INSERT INTO "tag" ("name") VALUES
('tech');

INSERT INTO "tag" ("name") VALUES
('fashion');

INSERT INTO "tag" ("name") VALUES
('beauty');

To connect to the appsmith_cms database from within Appsmith, go to the application sidebar. Click the plus icon near DB Queries, then click New Datasource, select PostgreSQL, and enter the connection details for your database.

Since you are on localhost, set the host address as host.docker.internal and the database name as appsmith_cms. Add your PostgreSQL username and password to the Authentication section and click Connect. Once connected, rename the new datasource as CMS.

Your App’s First Page: Create an Article

In this section, you’ll create the first UI view of your CMS application. It will be a form with several fields, for title, content, cover image, and a URL. These form fields will take in all the necessary data for creating an article.

On the sidebar, under Pages, a new page called Page1 already exists. Rename it as create_article_page.

Prepare the Data

Before building the form, prepare the queries necessary for creating an article.

Click the plus icon near DB Queries and click the New Query button near the CMS Datasource to create a new query. Rename it fetch_authors from the default name Query1. This will be useful in displaying all the available authors in your database. Paste the following code in the query box and run it:

SELECT * FROM author;

Create a new query called fetch_tags. This will be useful for displaying all available tags in your database. Paste the following code in the box and run it:

SELECT * FROM tag;

Create a new query called submit_article. This will be used to create a new article entry in the database.

INSERT INTO "article" ( "title", "subtitle", "content", "image", "author_id") 
VALUES
('{{create_article_form.data.title}}', 
'{{create_article_form.data.subtitle}}', 
'{{create_article_form.data.content}}', 
'{{create_article_form.data.cover_image}}', 
{{create_article_form.data.author}}
) returning "article_id"
;

Create a new query called create_article_tag. This will be used to create a new article_tag entry that associates a tag with an article.

INSERT INTO article_tag
  ("article_id", "tag_id")
VALUES
  (
    '{{submit_article.data[0].article_id}}', 
    '{{create_article_form.data.tags}}'
  );

Build the Page

Go to create_article_page > Widgets, and add a form to the page by clicking the plus icon. Drag and drop a Form widget to the page’s workspace. Click the settings gear to configure the form. Change the form name from form1 to create_article_form.

Next, let’s add a few fields along with labels.

To begin, add a Text widget and label it Title:, then drag the Input widget in front of it and change its name from input1 to title.

Below that, add a Text widget and label it Subtitle:, then drag the Input widget in front of it and change its name from input1 to subtitle.

Add a Text widget and label it Content:, then drag the Rich Text Editor widget in front of it and change its name from RichTextEditor1 to content. Delete the default text.

Add a Text widget and label it Cover Image:, then drag the Input widget in front of it and change its name from input1 to cover_image.

Add a Text widget and label it Author, then drag the Dropdown widget in front of it and change its name from Dropdown1 to author. In the options settings for this dropdown, add the following code:

{{
fetch_authors.data.map(
  (row)=>{

    return {label: row.name, value: row.author_id}
  }
)
}}

Add a Text widget and label it Tags:, then drag the Dropdown widget in front of it and change its name from Dropdown1 to tags. In the options settings for this dropdown, add the following code:

  {{
fetch_tags.data.map(
  (row)=>{

    return {label: row.name, value: row.tag_id}
  }
)
}}

Go to the onClick section of the Submit button’s settings, and select Execute a DB Query, choose the submit_article query, then in the onSuccess section, select Execute a DB Query > create_article_tag query. This creates an article entry in the database, and then creates the article_tag entry that links the tag and article together.

To test that it works, fill in the form with some test data and submit it. In the Article table in your database, you should see the new article row with data you just filled in.

The create_article_form

Your App’s Second Page: View Articles

Create a new page called all_articles_page. This page will be used to display all the articles available in the database.

Prepare the Query

Add a new query called fetch_articles and run it. This query will fetch all the articles in the database, as well the authors who wrote them.

SELECT art.*, aut.name as author FROM article art 
join author aut on aut.author_id = art.author_id;

Build the UI

On the all_articles_page, drag a table widget to the page and rename it articles_table. In the Table Data section of the table settings, set the value to {{fetch_articles.data}}. This will use data from the fetch_articles query defined above. By now, the table should be populated with a list of all the articles. The table automatically comes with search, pagination, and filter features.

Next, add a new column to the table and call it View. In the settings for View, set the Column Type as a button, label it View, and set the value for onClick as {{navigateTo('view_article_page', {"key": currentRow.article_id})}} after setting it to JS mode.

This means that when View is clicked, a user will go to the view_article_page.

Create a new page and name it view_article_page. Create a new query, get_article, and fill it as:

select art.*, tag.name as tag_name, tag.tag_id, auth.name as author from article art join
author auth on auth.author_id = art.author_id
left join article_tag at on at.article_id = art.article_id
left join tag on tag.tag_id = at.tag_id
where art.article_id = {{ appsmith.URL.queryParams.key }};
The all_articles_page

Go back to the view_article_page and add the following widgets and settings:

  1. Add a Text widget for the title and set the value of Text to {{get_article.data[0].title}}.
  2. Add another Text widget for the subtitle and set the value of Text to {{get_article.data[0].subtitle}}.
  3. Add an Image widget for the cover image and set the value of Image to {{get_article.data[0].image}}.
  4. Add a Text widget for the article content and set the value of Text to {{get_article.data[0].content}}.
  5. Add a Text widget for the article’s author and set the value of Text to Written By {{get_article.data[0].author}}
  6. To test that the configuration works, go to the all_articles_page and click View on any of the rows. This should take you to the view_articles_page with the actual article loaded.
The view_article_page

Your App’s Third Page: Edit an Article

On the all_articles_page, add a new column to the table. Then add a button called Edit to the column. In the settings for Edit, set the onClick section to JS and add {{navigateTo('edit_article_page',{"key": currentRow.article_id})}} as its value.

The new Edit button

Create a new page and name it edit_article_page. On this page, you’ll add a form to edit existing articles. You'll also make sure that the form is prefilled with the details of the article you want to edit.

Prepare the Data

Go to view_article_page > DB Queries > get_article and copy the get_article query to edit_article_page.

Go to the queries under the create_articles_page, click the three dots near fetch_authors, and select Copy to Page and then edit_article_page. Copy the query fetch_tags to the edit_article_page as well. Under the edit_article_page, you should see all the copied queries. Make sure that the getArticlesCopy ends with { appsmith.URL.queryParams.key }}; instead of {{ }};.

Create a new query edit_article_query and add:

 update article 
SET title = '{{edit_article_form.data.title}}',
    subtitle = '{{edit_article_form.data.subtitle}}',
    content = '{{edit_article_form.data.content}}',
    image = '{{edit_article_form.data.cover_image}}',
    author_id = {{edit_article_form.data.author}}
  WHERE article_id = {{ get_articleCopy.data[0].article_id }};

Create a new query, new_article_tag_query, and add:

INSERT INTO article_tag
  (article_id, tag_id)
VALUES
  (
    '{{ get_articleCopy.data[0].article_id }}',
    '{{ edit_article_form.data.tag }}'
  );

Create a new query, delete_old_article_tags, and add:

DELETE FROM article_tag 
WHERE article_id = {{get_articleCopy.data[0].article_id}};

Build the Page

To build the edit_article_page page, add a Form widget to the page, click the settings gear, and rename the form edit_article_form. Change the form label to Edit an Article.

Add six text widgets to the form and label them Title, Subtitle, Content, Cover Image, Author, and Tag respectively, just like you did on the create_article_page.

Drag the Input widget in front of Title and Subtitle and change their names from input1 to title and subtitle respectively. Open the title widget and set default text as {{get_articleCopy.data[0].title}}. Also set default text for Subtitle as {{get_articleCopy.data[0].subtitle}}.

Drag the Rich Text Editor widget in front of the Content label and change its name from input1 to content. Set the widget's default text as {{get_articleCopy.data[0].content}}.

Drag the Input widget in front of the Cover Image label. Rename the widget cover_image. Set the default text as {{get_articleCopy.data[0].image}}.

Drag a dropdown widget in front of both the Author and Tag labels. For Author, change its name from Dropdown1 to author and set the default text as the following:

{{
  fetch_authorsCopy.data.map(
  (row)=>{

    return {label: row.name, value: row.author_id.toString()}
  }
  )
}}

And the Default Option as {{get_articleCopy.data[0].author_id}}.

For the Tag field, change its name from Dropdown2 to tag and set the options as:

  {{
    fetch_tagsCopy.data.map(
    (row)=>{

      return {label: row.name, value: row.tag_id.toString()}
    }
    )
  }}

And the Default Option as {{get_articleCopy.data[0].tag_id}}.

In the Submit button's settings, go to the onClick section and click JS. Set the value as:

 {{edit_article_query.run(() => delete_old_article_tags.run(() => new_article_tag_query.run(() => get_articleCopy.run()) ), () => {})}}

To test that the configuration works, go to the all_articles_page and click the Edit button on one of the rows. This should bring you to the edit_article_page, with the form prefilled with the selected row's data.

From here you can edit the article and then submit. Confirm that the article got edited successfully from the all_articles_page by looking up the row to see if the data changed.

The edit_article_form

Your App’s Fourth Page: Manage Tags and Authors

Create a new page called authors_and_tags_page. On this page, you'll be able to view all the Authors and Tags. You'll also add the ability to remove and add tags.

Prepare the Queries

Go to the create_article_page > DB Queries and copy fetch_authors and fetch_tag to authors_and_tags_page.

Create a new query, create_tag_query, and paste in the following:

INSERT INTO tag
  (name)
VALUES
  (
    '{{create_tag_modal.data.tag_name}}'
  );

Create a new query, delete_article_tag_query, and paste in the following:

INSERT INTO tag
 DELETE FROM article_tag 
WHERE tag_id = {{tags_table.selectedRow.tag_id}};

Create another query, delete_tag, and add the following code:

DELETE FROM tag WHERE tag_id= {{tags_table.selectedRow.tag_id}}

Build the Page UI

To start building the page UI, add a text widget and name it Authors. Underneath, add a table widget and rename it author_table. Set the Table Data as {{fetch_authorsCopy.data}}. Reload the page.

Add a new column called Action. Go to Action's settings, set its column type as Button, and label the button as View. In the onClick section, set it as JS, and the value as {{showModal('view_author_modal')}}.

You just created a button on the table called View. When this button is clicked, you want it to open a modal called view_author_modal.

The Authors table

To create view_author_modal, drag a Modal widget to the page and rename it view_author_modal. Change the Modal Title text to View Author, set the Modal Type as a Form Modal, and delete the buttons in the modal. Dismiss the modal and click one of the View buttons on the Authors table. This should open up the modal.

Now add a Text widget and set the Text value to {{author_table.selectedRow.name}} in the settings.

Add an Image widget and give it an Image value of {{author_table.selectedRow.profile_picture}}.

Add a Text widget and label it LinkedIn:. In front of it, add another Text widget and give it a Text value of {{author_table.selectedRow.linkedin}}.

Add a Text widget and label it GitHub:. In front of it, add another Text widget and give it a Text value of {{author_table.selectedRow.github}}.

At this point, you should see all of the Author's information rendered on the modal.

Screenshot of the view_article_modal

Next, you need to create a table to display all the tags. Start by adding a Text widget and labeling it Tags. Underneath, add a Table widget and rename it tags_table. Set the Table Data as {{fetch_tagsCopy.data}} and reload the page.

Add a new column called Action. Go to Action's settings, set its column type as Button, and label it as remove. Set the button to Red as well. In the onClick section, enable JS and paste the value as {{delete_article_tag_query.run(() => delete_tag.run(), () => {})}}.

You can test deleting a tag by clicking one of the remove buttons on the Tags table.

Add a Button widget in the bottom right corner underneath the Tags table and label it Add Tag. Next, in the button's onClick settings, click JS and paste the value {{navigateTo('create_tag_page','SAME_WINDOW')}}. Here you’ve configured the Add Tag button to open a new page called create_tag_page.

The Tags table

Create a new page called create_tag_page. When the Add Tag button is clicked, it should go to this new page.

Go to DB Queries and create a new query called create_tag_query. Paste in the following:

INSERT INTO tag
(name)
VALUES
(
  '{{create_tag_form.data.tag_name }}'
);

Go back to the create_tag_page, and drag a Form widget into the workspace. Rename it create_tag_form. Then inside the form, add a Text widget and label it Add Tag.

Underneath, add a Text widget and label it Name:. In front of it add an input widget and rename it tag_name.

Go to the onClick section of the Submit button settings and select Execute a DB Query. Choose the create_tag_query. In the onSuccess section, select Navigate to, and for Page Name enter authors_and_tags_page. This means you want to navigate to the Tags page once a new tag has been created.

Test creating a new tag and checking that it is present on the Tags table.

The create_tag_page

Conclusion

You've seen how easy and fast it is to build a content management system on Appsmith. You’ve connected to a database and built pages and made them interactive. You’ve experimented with how Appsmith’s widgets work, and you’ve learned to customize them for your purposes.

If you’re looking for a fast way to create a CMS or some other internal tool with minimal need for developer hours, consider building it with Appsmith.

Square
Try Appsmith
Inline editing in the table widget, integration with Airtable, and more
2
August
2022
Announcement

Inline editing in the table widget, integration with Airtable, and more

Inline editing in the table widget, integration with Airtable, and more
Vihar Kurama
0
 minutes ↗
#
announcement
Announcement

In July, we squashed 102 of the peskiest bugs and shipped 34 top requested features over and above under-the-hood performance and usability improvements. There’s a new table widget that’s so much more powerful, an Airtable integration, and cleaner Google Sheets queries with 178 commits in 22 days just for that enhancement alone! You can tell we have got our ears close to you. Keep it coming, guys. We love it all, and we are always listening.

#BigThings

The swanky new table widget

Fact: Just 25% of you tell us who you are and how you use Appsmith. We are okay with that. We respect your privacy.
Assertion: Our usage numbers should be 4X more.
Inference: When we say the Table widget, ever since we launched it, has been used a crazy 820,000 times by 6,840 users, we actually mean it's been used a lot more and is second only to the Button.
Takeaway: Give it more love.

Introducing the new Table widget

Everything you asked for from the table and more is packed into this massive update. Here’s three that should make you sit up.

  • With inline editing, you can now forget about writing queries to edit data by cell, row, or column. You just get your data into the table and edit on the screen. We heavylift the queries, updating the database, and making sure it sticks–all behind the scenes. Clicksaver? Lifesaver? Timesaver? All three and more? We think so, too.
  • You know how you have always wanted to refer to custom column names more naturally than typing customColumn1, customColumn2, and so on in your queries? Yep. Done. No matter what the name of your column, reference away just as naturally as you name them.
  • Themes have been making apps pretty for a while, but Tables stayed rebelliously aloof from that prettiness. We have now made them fall in line with Themes, so if you want shades of blue and Roboto, you got it in Tables, too.

There’s a whole lot more that you are going to have to see for yourself.

Airtable integration, out in the sun

Our Airtable integration gave UI facelifts to the low-code datasource. It is now out of beta, ready for its moment in the sun.

Connect with a Airtable base in two minutes, and start building your apps without worrying about complex data workflows.

 

Auto-indent here to make a dent

On our latest version? Tried the JavaScript editor yet? No? Do that now and you don’t have to read on anymore. 

Oh, okay. You are still here. Fine. We will show you.

Automatically pretty code is pretty cool, huh? More about it here.

#UpdateThings

“Hide Error Messages, Hide”

Infuriating little things, error messages, that bring up existential questions, right? And when they showed up all the time, they got us to, “Frustrating!”. They don’t anymore, only showing up when a widget is visible and clicked.

“How much to upgrade?”

Got your Appsmithing going, but a paid feature’s in your way? Fret not, self-hoster. We got your back with a command-line feature that estimates your usage in thirty seconds. Click this and all shall be revealed.

Run any Appsmith branch locally

With something like ./scripts/local_testing.sh chore/local-testing, running any branch as a FAT container is a breeze. Make sure Docker’s installed and running, port 80 is open, and you add arguments if you don’t want to run the release branch.

Errors, alerts, and logs

Two new modules, logger.js and mailer.js now store backup errors and alert you to them—helpful to get you on top of the error and aid find-and-fix.

While logger.js is on by default, mailer.js needs appsmithctl backup --error-mail to get humming.

Just two of the many, many ways we got your back(up).

Moving Google Sheets to UQI 

Google Sheets is a popular data source. We didn’t dig up numbers, but you can take out word for it. UQI stands for Unified Query Interface and affords standardization for queries. Made sense to get queries to Sheets working better and looking neater, too.

#AsAlwaysThings

If wishes were fishes, round-ups would be essays. Wishes aren’t fishes. So, head over to v1.7.9 if you closed our Release Notes in-app pop-up one of four different ways—yeah, we are fixing it—and see What Happened In July Appsmith style.

Need a new datasource connected?   ||    Discord    ||    YouTube    ||    Twitter

Track and manage bugs effectively using Appsmith and Airtable
1
August
2022
Tutorial

Track and manage bugs effectively using Appsmith and Airtable

Track and manage bugs effectively using Appsmith and Airtable
Vidushi Gupta
0
 minutes ↗
#
tutorial
#
dashboard
#
announcement
Tutorial

Airtable is a popular choice for developers who want to manage tabular data easily. While it's easy to use Airtable as a backend, it can be challenging to build a custom UI from scratch. This is where Appsmith comes in. With Appsmith's native Airtable integration, you can create dashboards, CRUD apps, and internal tools in minutes.

In this tutorial, we'll use an Airtable base to build an issue tracker. We'll start by creating a database in Airtable and then importing our data into Appsmith and building on top of it using JavaScript. 

With this application, users can:

  • Connect to their Airtable base.
  • Add a new bug/issue
  • Update the existing issue
  • View the current bugs in the management tool.

Let's jump in!

Step 1:  Getting started

Create a new Appsmith App 

First, we need to create a new application in Appsmith so we can build it out.

  • Visit https://www.appsmith.com to create a new account or login in to an existing one.
  • Create a new application in your preferred organization and edit it.

Connect to Airtable

Now, we need to add your Airtable datasource to the app. In this case, we will clone an existing Airtable sample to provide our data. 

  • Create a new datasource by clicking ‘+’ on the Datasources tab from the entity explorer and then select Airtable.

  • Rename the datasource. Select API Key as the Authentication Type and enter your API Key in the input field. Hit Save.

  • Choose a workspace and a base in the dialog box and hit 'Create Table.'
  • Go to https://airtable.com/api and select the base titled 'All bugs and issues'
  • In the 'Introduction' section of the documentation, copy the Base ID (highlighted in green in the picture below)

  • Select the "Bugs and issues Table" on the left pane. Copy the table name highlighted in green in the image below.

Step 2 : Set up UI for the App

Wireframe

Here is the wireframe for what we are trying to create.

Including the modal that is used to add new bugs.

Create your widgets

Using the wireframe as a guide, create the UI for the application using the drag and drop editor. Here is a suggested process.

  • Choose a preferred theme from the Theme properties option in the property pane on the right.
  • Add a container widget with a text widget for your app's header.
  • Three (or as many as you like) stats boxes on the canvas to display essential statistics at a glance.
  • A container with a text, icon button, and list widget for showing a list of all the issues.
  • A container with text, button, select and list widgets for showing details of the selected issues.
  • A modal with a text, icon button, and JSON form widgets for adding a new bug entry.

Step 3 : Binding data on widgets

Listing records on the List widget

The list of bugs/issues should look something like this. In order to populate the data, create a new query and bind the results to the text.

  • Create a new query from the left pane which uses the Airtable datasource you created in the first step. Rename the query to getBase and choose the Commands to be List records. We chose this command because we would like to list all the bugs and issues in our app. Enter the Base ID and Table Name you copied in the steps above. 
  • Hit Run and you should see a JSON response generated which lists the records. 
  • To bind this response to the list widget, we would first create a JSObject that maps the fields from the records. Create a new JSObject and paste in the following snippet.

getAirTableFields: () => {
  return getBase.data.records.map((record) => {
    let row = record.fields;
    row["id"] = record.id;
    return row;
  });
};


  • In this JSObject, we get the response from the GetBase query, map the fields, and get the id for every row in the table. 
  • Bind the list with this data using  {{JSObject1.getAirTableFields()}}
  • For getting the bug name and the source, bind the text widgets within the list with {{currentItem.Name}} and {{currentItem.Bug_source}} respectively.

Getting details of the selected bug

When we click on an item from the list, we should populate the view container with details of the selected issue


  • In order to get details about the selected bug on the container placed on the right, we would just use the {{List.selectedItem.attribute}} for all the details you wish to display. For example, The bug title can be displayed using {{List1.selectedItem.Name}}, for Associated features write {{List1.selectedItem.Associated_features}}, For priority write {{List1.selectedItem.Priority}}. So on and so forth. 
  • For a closed/open bug field, use the ternary format to display the status. {{List1.selectedItem.Closed == '1'? "Closed": "Open"}}
  • To bind the attachments for the selected bug, write {{List1.selectedItem['Attachments']}} to bind data on the list widget in the right container. 
  • Just like binding the bug details, in the image widget enter {{currentItem.url}} in the property pane to display the image attached
  • Use {{currentItem.filename}} and {{currentItem.type}} to display the file name and type on the text widget.

Displaying statistics on the statsboxes

These statsboxes should help display important information at a glance from this database. As the number of issues grows, this will give us a quick understanding of the status.

  • In order to populate the statsboxes with statistics, we would create a JSObject function that maps to fields and then to Priority within the same JSON response and check if the value is High, meaning the priority is set to high. What we get in the response is our desired statistic. 

highPriority: () => {
  const high = getBase.data.records.map((record) => record.fields.Priority);
  return high.filter((currentItem) => currentItem == "High").length;
};

  • Bind this output in the text widget using {{JSObject1.highPriority()}}
  • In the very same manner, write a function and bind the output for the number of bugs labeled open and critical

Adding a new Bug/Issue

When clicking the button to add an issue, a modal appears with a form that creates a new entry. It looks like this:

  • Set the Modal to open on onClick of the icon button on the top right corner of the container on the left. 

  • Populate the JSON Form with source data by pasting the following.

{
"fields": { 
    "Bug Title": "",
    "Priority": "",
    "Assigned To":"",
    "Status": "",
    "Screenshots": [
      {
        "URL": ""
      }
    ],
    "Bug Description": "",
    "Bug Source": "",
    "Features Associated": "",
    "Created by": ""
}
}


You can customize the field configuration as per your requirement. Here’s what the JSON Form looks like https://www.loom.com/share/1087b1e8932846feaf3dd03e8b3bb780

  • To insert a new record, we’ll write a new query. 
    Create a new query and name it as InsertQuery. Choose the command to be Create Records. Add in your Base ID and Table Name. For the Records, bind the form data from the JSON form for every field. 

[
  {
    "fields": {
      "Name": "{{JSONForm1.formData.fields['Bug Title']}}",
      "Priority": "{{JSONForm1.formData.fields['Priority']}}",
      "Status": "{{JSONForm1.formData.fields['Status']}}",
      "Attachments": [
        {
          "url": "{{JSONForm1.formData.fields.Screenshots[0].URL}}"
        }
      ],
      "Assigned_to": "{{JSONForm1.formData.fields['Assigned To']}}",
      "Description": "{{JSONForm1.formData.fields['Bug Description']}}",
      "Bug_source": "{{JSONForm1.formData.fields['Bug Source']}}",
      "Associated_features": "{{JSONForm1.formData.fields['Features Associated']}}",
      "Created_by": "{{JSONForm1.formData.fields['Created by']}}"
    }
  }
]

  • We’ll make a new JSObject function to run multiple queries when the Add Bug button is clicked in the form

addBug: async () => {
  InsertQuery.run();
  getBase.run();
  closeModal("Modal2");
};
  • Now bind this function on onClick of the Add Bug button in the JSON Form.

Update fields of a bug

This query/button can help update the details of the bug. In this case, we update the priority and statuses. 

To update the priority and status of a selected bug, an Update Records query would be used. 

  • Create a new query and rename it as updateQuery. Choose the command to be Update Records and enter your BaseID and Table Name. In the records field, paste the following to get the selectedOptionValue of the select widgets

[
    {
      "id": {{List2.selectedItem.id}},
      "fields": {  
        "Priority": {{Select1.selectedOptionValue}},
        "Status":{{Select2.selectedOptionValue}}
      }
    }
]

  • Now, bind this query to run on onClick of the update button.

Final thoughts

And that’s it! You have your bug tracker application ready using Appsmith’s native Airtable integration 🎉

First, you created a new Appsmith application and connected it to Airtable. Then you created the UI for your app using the drag and drop tools in Appsmith. Finally, you tied the data from Airtable to the UI widgets. Your final app should look similar to this:

Please use this form to contact us if you have any template requests for internal tools that you need, and we will get to work! 

If you have any questions, contact us on Discord. You can also keep up with us on Twitter and YouTube.

Build Custom UI on top of Airtable data
25
July
2022
Announcement

Build Custom UI on top of Airtable data

Build Custom UI on top of Airtable data
Rishabh Kaul
0
 minutes ↗
#
integrations
#
databases
#
announcement
Announcement

Today, our integration with Airtable comes out of beta and is available for everyone 🎉! You can now build custom UIs and interact with applications built on Airtable, with minimal configuration.

While it is possible to use the default API interface to connect to Airtable, we wanted to make it easier for you to directly connect your Airtable account and create applications faster than ever. This new data connector introduces a number of features:

  • Integration located in the “Datasources” section
  • Connect to your Airtable account with either an API Key or a Bearer Token (OAuth 2.0)
  • Create queries to fetch, create, retrieve, update and delete data from a datasource using the Appsmith query editor. 
  • List command lets you display all the data from Airtable, and can also present data that has been filtered and sorted based on fields, records, time zones, etc. 

For details and information on how to use this new integration (with videos!), check out our Airtable documentation here. See it in action on our full tutorial here, where we build an issue tracker with Airtable as backend. As always, let us know what you think!

What’s a Rich Text element?

asdsadasdsa

asdsadasdsa

The rich text element allows you to create and format headings, paragraphs, blockquotes, images, and video all in one place instead of having to add and format them individually. Just double-click and easily create content.

sfdfsdfds

dsfdsfdsf

adfkaldf

The rich text element allows you to create and format

sadadasdasdas dsada sadas asd ad

Static and dynamic content editing

  1. vdfgdgd
  2. gjgjg

A rich text element can be used with static or dynamic content. For static content, just drop it into any page and begin editing. For dynamic content, add a rich text field to any collection and then connect a rich text element to that field in the settings panel. Voila!

How to customize formatting for each rich text

Headings, paragraphs, blockquotes, figures, images, and figure captions can all be styled after a class is added to the rich text element using the "When inside of" nested selector system.

swzdswxzdsw