Skip to content

Instantly share code, notes, and snippets.

@dinhtungdu
Last active April 18, 2018 12:38
Show Gist options
  • Save dinhtungdu/8595fa4212eded920ed76232f03dfb06 to your computer and use it in GitHub Desktop.
Save dinhtungdu/8595fa4212eded920ed76232f03dfb06 to your computer and use it in GitHub Desktop.
Building a Notebook Web app with WordPress and React
|-blank
|—--functions.php
|—--index.php
|—--style.css
<?php
add_action( 'cmb2_init', 'register_taxonomy_metabox' );
function register_taxonomy_metabox() {
$prefix = 'cat_';
$cmb_term = new_cmb2_box( array(
'id' => $prefix . 'fields',
'title' => esc_html__( 'Category Metabox', 'cmb2' ),
'object_types' => array( 'term' ),
'taxonomies' => array( 'category', 'post_tag' ),
'new_term_section' => true,
'show_in_rest' => WP_REST_Server::READABLE,
) );
$cmb_term->add_field( array(
'name' => esc_html__( 'Icon Class', 'cmb2' ),
'id' => $prefix . 'icon_class',
'type' => 'text',
) );
}
<?php
add_action( 'cmb2_init', 'register_taxonomy_metabox' );
function register_taxonomy_metabox() {
$prefix = 'cat_';
$cmb_term = new_cmb2_box( array(
'id' => $prefix . 'fields',
'title' => esc_html__( 'Category Metabox', 'cmb2' ),
'object_types' => array( 'term' ),
'taxonomies' => array( 'category', 'post_tag' ),
'new_term_section' => true,
'show_in_rest' => WP_REST_Server::READABLE,
) );
$cmb_term->add_field( array(
'name' => esc_html__( 'Icon Class', 'cmb2' ),
'id' => $prefix . 'icon_class',
'type' => 'text',
) );
}
add_action( 'cmb2_init', 'register_snippet_fields' );
function register_snippet_fields() {
$prefix = 'cells_';
/**
* Repeatable Field Groups
*/
$cmb_group = new_cmb2_box( array(
'id' => $prefix . 'metabox',
'title' => esc_html__( 'Snippet', 'cmb2' ),
'object_types' => array( 'post', ),
'show_in_rest' => WP_REST_Server::READABLE,
) );
$group_field_id = $cmb_group->add_field( array(
'id' => $prefix . 'group',
'type' => 'group',
'options' => array(
'group_title' => esc_html__( 'Cell {#}', 'cmb2' ),
'add_button' => esc_html__( 'Add Another Cell', 'cmb2' ),
'remove_button' => esc_html__( 'Remove Cell', 'cmb2' ),
'sortable' => true, // beta
),
) );
$cmb_group->add_group_field( $group_field_id, array(
'name' => esc_html__( 'Cell Title', 'cmb2' ),
'id' => 'title',
'type' => 'text',
) );
$cmb_group->add_group_field( $group_field_id, array(
'name' => esc_html__( 'Code', 'cmb2' ),
'id' => 'code',
'type' => 'textarea_code',
) );
$cmb_group->add_group_field( $group_field_id, array(
'name' => esc_html__( 'Language', 'cmb2' ),
'id' => 'language',
'type' => 'text',
) );
}
<?php
header( “Location: https://enforty.com” );
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
<link rel="stylesheet" href="%PUBLIC_URL%/css/antd.min.css">
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
add_action( 'cmb2_init', 'register_snippet_fields' );
function register_snippet_fields() {
$prefix = 'cells_';
/**
* Repeatable Field Groups
*/
$cmb_group = new_cmb2_box( array(
'id' => $prefix . 'metabox',
'title' => esc_html__( 'Snippet', 'cmb2' ),
'object_types' => array( 'post', ),
'show_in_rest' => WP_REST_Server::READABLE,
) );
$group_field_id = $cmb_group->add_field( array(
'id' => $prefix . 'group',
'type' => 'group',
'options' => array(
'group_title' => esc_html__( 'Cell {#}', 'cmb2' ),
'add_button' => esc_html__( 'Add Another Cell', 'cmb2' ),
'remove_button' => esc_html__( 'Remove Cell', 'cmb2' ),
'sortable' => true, // beta
),
) );
$cmb_group->add_group_field( $group_field_id, array(
'name' => esc_html__( 'Cell Title', 'cmb2' ),
'id' => 'title',
'type' => 'text',
) );
$cmb_group->add_group_field( $group_field_id, array(
'name' => esc_html__( 'Code', 'cmb2' ),
'id' => 'code',
'type' => 'textarea_code',
) );
$cmb_group->add_group_field( $group_field_id, array(
'name' => esc_html__( 'Language', 'cmb2' ),
'id' => 'language',
'type' => 'text',
) );
}
import React, { Component } from 'react';
import logo from './logo.svg';
import './style.css';
class App extends Component {
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
</div>
);
}
}
export default App;
import React, { Component } from 'react';
import './style.css';
import Layout from 'antd/lib/layout';
import AppHeader from '../AppHeader';
import Sidebar from '../Sidebar';
const { Content } = Layout;
const App = () => (
<div className="App">
<Layout className="ant-layout-has-sider">
<Sidebar/>
<Layout>
<AppHeader/>
<Content className="App__Content">
This is app content area.
</Content>
</Layout>
</Layout>
</div>
);
export default App;
.App {
font-size: 14px;
}
.App__Content {
margin: 24px 16px;
background: #fff;
display: flex;
}
import React from 'react';
import './style.css';
import Layout from 'antd/lib/layout';
import SearchForm from '../SearchForm';
const { Header } = Layout;
const AppHeader = () => (
<Header className="App__Header">
<SearchForm/>
</Header>
);
export default AppHeader;
.App__Header {
background: #fff;
padding: 0 16px;
height: 60px;
line-height: 60px;
display: flex;
align-items: center;
box-shadow: 4px 4px 40px 0 rgba(0, 0, 0, .05);
}
import React from 'react';
import './style.css';
const Logo = () => (
<div className="Logo">
<img src="/images/logo.png" alt="enforty Notes"/>
</div>
);
export default Logo;
.Logo {
padding: 10px 20px;
/*text-align: center;*/
}
.Logo img {
max-width: 80px;
}
import React from 'react';
import Input from 'antd/lib/input';
import Icon from 'antd/lib/icon';
import './style.css';
const SearchForm = ({ dispatch }) => {
let term;
return (
<div className="SearchForm">
<Input
prefix={<Icon type="search"/>}
placeholder="Search.."
ref={node => {
term = node;
}}
/>
</div>
);
};
export default SearchForm;
.SearchForm {
width: calc(100% - 200px);
min-width: 300px;
}
.SearchForm input.ant-input {
font-size: 16px;
border-color: transparent;
}
.SearchForm .ant-input-affix-wrapper:hover input.ant-input {
border-color: transparent;
}
.SearchForm input:focus {
box-shadow: none;
}
.SearchForm .ant-input-affix-wrapper .ant-input:not(:first-child) {
padding-left: 50px;
}
.SearchForm i {
font-size: 20px;
}
.SearchForm .ant-input-affix-wrapper:hover i {
color: #49a9ee;
}
import React from 'react';
import './style.css';
import Layout from 'antd/lib/layout';
import Icon from 'antd/lib/icon';
import Menu from 'antd/lib/menu';
import Logo from '../Logo';
const { Sider } = Layout;
const MenuItem = Menu.Item;
const MenuItemGroup = Menu.ItemGroup;
class Sidebar extends React.Component {
render() {
return (
<Sider
className="Sidebar"
collapsible
breakpoint="sm"
trigger={null}
>
<div className="Sidebar__Header">
<Logo />
<Icon
className="trigger"
type={ 'menu-fold'}
/>
</div>
<Menu
className="Sidebar__Menu"
mode="inline"
theme="light"
>
<MenuItemGroup key="category" title={<span><Icon type="book"/><span className="txt">Category</span></span>}>
<MenuItem>
<i className="anticon anticon-paper-clip"></i>
<span className="txt">Menu Item</span>
</MenuItem>
</MenuItemGroup>
<MenuItemGroup key="tag" title={<span><Icon type="tag"/><span className="txt">Tag</span></span>}>
<MenuItem>
<i className="anticon anticon-paper-clip"></i>
<span className="txt">menuitem</span>
</MenuItem>
</MenuItemGroup>
</Menu>
</Sider>
);
}
}
export default Sidebar;
.Sidebar {
text-align: left;
background: #fff;
border-right: 1px solid #e9e9e9;
}
.Sidebar__Header {
display: flex;
align-items: center;
height: 61px;
border-bottom: 1px solid #e9e9e9;
}
.Sidebar__Header .trigger {
font-size: 18px;
line-height: 45px;
padding: 0 16px;
cursor: pointer;
transition: color .3s;
margin-left: auto;
}
.Sidebar.ant-layout-sider-collapsed .Logo {
display: none;
}
.Sidebar.ant-layout-sider-collapsed .trigger {
margin-right: auto;
}
.Sidebar .ant-menu-inline {
border-right: none;
}
.ant-menu-inline .ant-menu-item, .ant-menu-inline .ant-menu-submenu-title {
font-size: 14px;
}
.Sidebar .ant-menu-item i {
margin-right: 10px;
}
.Sidebar.ant-layout-sider-collapsed .txt {
display: none;
}
.Sidebar .ant-menu-item-group-title {
background: #f9f9f9;
}
.Sidebar .ant-menu-item-group-title i {
display: none;
}
.Sidebar.ant-layout-sider-collapsed .ant-menu-item-group-title i {
display: block;
}
import React from ‘react’;
import ReactDOM from ‘react-dom’;
import ‘./index.css’;
import App from ‘./components/App’;
import registerServiceWorker from ‘./registerServiceWorker’;
/*
Theme Name: Blank
Version: 1.0.0
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment