[Spring Boot][java] app開発3

SpringBootのリポジトリとは?
-> DBへのアクセスを自動で作成する便利インターフェース
-> DBへのCRUDを自動で実装してくれる
なるほど

Listとは?
-> Javaのリスト(List)とは、重複した要素を含むことができる順序の付けられたコレクション
-> 配列とは異なる

ReservationRepository.java

package mrs.domain.repository.reservation;

import java.util.List;

import mrs.domain.model.ReservableRoomId;
import mrs.domain.model.Reservation;

import org.springframework.data.jpa.repository.JpaRepository;

public interface ReservationRepository extends JpaRepository<Reservation, Integer>{
	List<Reservation> findByReservableRoom_ReservableRoomIdOrderByStartTimeAsc(
			ReservableRoomId reservableRoomId);
}

MeetingRoomRepository.java

package mrs.domain.repository.room;

import org.springframework.data.jpa.repository.JpaRepository;

import mrs.domain.model.MeetingRoom;

public interface MeetingRoomRepository extends JpaRepository<MeetingRoom, Integer>{
	
}

Serviceとは?
-> ビジネスロジックを実装するクラス
-> Controllerはリクエストの窓口になるクラス
ん、ビジネスロジックはcontrollerではなく、serviceで書くのか。ちょっと混乱するな。

ReservationService.java

package mrs.domain.service.reservation;

import java.util.List;

import mrs.domain.model.*;
import mrs.domain.repository.reservation.ReservationRepository;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class ReservationService {
	@Autowired
	ReservationRepository reservationRepository;
	
	public List<Reservation> findReservations(ReservableRoomId reservableRoomId){
		return reservationRepository.findByReservableRoom_ReservableRoomIdOrderByStartTimeAsc(
				reservableRoomId);
	}
}

Serviceの中のpublic List<*>がJavaの構文でないような印象だが、どういう事なんだ?

package mrs.domain.service.reservation;

import java.util.List;

import mrs.domain.model.*;
import mrs.domain.repository.reservation.ReservationRepository;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class ReservationService {
	@Autowired
	ReservationRepository reservationRepository;
	@Autowired
	ReservableRoomRepository reservableRoomRepository;
	
	public Reservation reserve(Reservation reservation) {
		ReservableroomId reservableRoomId = reservation.getReservableRoom().getReservableRoomId();
		ReservableRoom reservable = reservableRoomRepository.findOne(reservableRoomId);
		if(reservable == null) {
			
		}
		boolean overlap = reservationRepository.findByReservableRoom_ReservableRoomIdOrderByStartTimeAsc(reservableRoomId)
				.stream()
				.anyMatch(x -> x.overlap(reservation));
		if(overlap) {
			
		}
		reservationRepository.save(reservation);
		return reservation;
	}

ReservationsController.java

package mrs.app.reservation;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import mrs.domain.model.*;
import mrs.domain.service.reservation.*;
import mrs.domain.service.room.RoomService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping("reservations/{date}/{roomId}")
public class ReservationsController {
	@Autowired
	RoomService roomService;
	@Autowired
	ReservationService reservationService;
	
	@ModelAttribute
	ReservationForm setUpForm() {
		RservationForm form = new ReservationForm();
		form.setStartTime(LocalTime.of(9, 0));
		form.setEndTime(LocalTime.of(10, 0));
		return form;
	}
	
	@RequestMapping(method = RequestMethod.GET)
	String reserveForm(@DateTimeFormat(iso=DateTimeFormat.ISO.DATE) @PathVariable("date") LocalDate date,
			@PathVariable("roomId") Integer roomId, Model model) {
		ReservableRoomId reservableRoomId = new ReservableRoomId(roomId, date);
		List<Reservation> reservations = reservationService.findReservations(reservableRoomId);
		
		List<LocalTime> timeList =
				Stream.iterate(LocalTime.of(0, 0), t -> t.plusMinutes(30))
				.limit(24 * 2)
				.collect(Collectors.toList());
		
		model.addAttribute("room", roomService.findMeetingRoom(roomId));
		model.addAttribute("reservations", reservations);
		model.addAttribute("timeList", timeList);
		model.addAttribute("user", dummyUser());
		return "reservation/reserveForm";
	}
	
	private User dummyUser() {
		User user = new User();
		user.setUserId("taro-yamada");
		user.setFirstName("taro");
		user.setLastName("Yamada");
		user.setRoleName(RoleName.USER);
		return user;
	}
}
package mrs.app.reservation;

import java.io.Serializable;
import java.time.LocalTime;

import javax.validation.constraints.NotNull;

import org.springframework.format.annotation.DateTimeFormat;

public class ReservationForm implements Serializable {
	@NotNull(message = "必須です")
	@DateTimeFormat(pattern = "HH:mm")
	private LocalTime startTime;
	
	@NotNull(message = "必須です")
	@DateTimeFormat(pattern = "HH:mm")
	private Localtime endTime;
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<title th:text="|${#temporals.format(date, 'yyyy/M/d')}の${room.roomName}|">2021/01/29の豊洲</title>
</head>
<body>

<div>
<a th:href="@{'/rooms/' + ${date}">会議室一覧へ</a>
</div>

<form th:object="${reservationForm}"
	th:action="@{'/reservations/' + ${date} + '/' + ${roomId}}" method="post">
	会議室: <span th:text="${room.roomName}">銀座</span>
	<br>
	予約者名: <span th:text="${user.lastName + ' ' + user.firstName}">山田太郎</span>
	// 省略

うーむ、全体的な流れを掴むには良いが、もう少し入門的なところからやりたい。。

[Spring Boot][java] app開発2

src/main/resources/schema.sql

DROP TABLE IF EXISTS meeting_room CASCADE;
DROP TABLE IF EXISTS reservable_room CASCADE;
DROP TABLE IF EXISTS reservation CASCADE;
DROP TABLE IF EXISTS usr CASCADE;

CREATE TABLE IF NOT EXIST meeting_room(
	room_id SERIAL NOT NULL,
	room_name VARCHAR(255) NOT NULL,
	PRIMARY KEY (room_id)	
);


CREATE TABLE IF NOT EXIST reservable_room(
	reserved_data DATE NOT NULL,
	room_id INT4 NOT NULL,
	PRIMARY KEY(reserved_date, room_id)
);

CREATE TABLE IF NOT EXIST meeting_room(
	reservation_id SERIAL NOT NULL,
	end_tim TIME NOT NULL,
	start_time TIME NOT NULL,
	reserved_date DATE NOT NULL,
	room_id INT4 NOT NULL,
	user_id VARCHAR(255) NOT NULL,
	PRIMARY KEY(reservation_id)
);

CREATE TABLE IF NOT EXIST meeting_room(
	user_id VARCHAR(255) NOT NULL,
	first_name VARCHAR(255) NOT NULL,
	last_name VARCHAR(255) NOT NULL,
	password VARCHAR(255) NOT NULL,
	role_name VARCHAR(255) NOT NULL,
	PRIMARY KEY (user_id)
);

repository class

package mrs.domain.repository.room;

import java.time.LocalDate;
import java.util.List;

import mrs.domain.model.ReservableRoom;
import mrs.domain.model.ReservableRoomId;

import org.springframework.data.jpa.repository.JpaRepository;

public interface ReservableRoomRepository extends JpaRepository<ReservableRoom, ReservableRoomId>{
	List<ReservableRoom> findByReservableRoom_reservedDateOrderByReservableRoomId_roomIdAsc(LocalDate reservedDate);
}

-> importで先ほど作ったmodelを読み込んでますね。なるほど、少しわかってきた。

domain/service/RoomService.java

package mrs.domain.repository.room;

import java.time.LocalDate;
import java.util.List;

import mrs.domain.model.ReservableRoom;
import mrs.domain.repository.room.ReservableRoomRepository;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class RoomService {
	
	@Autowired
	ReservableRoomRepository reservableRoomRepository;
	
	public List<ReservableRoom> findReservableRooms(LocalDate date){
		return reservableRoomRepository.findByReservableRoomId_reservedDateOrderByReservableRoomId_roomIdAsc(date);
	}
}

app/room/RoomsController.java

package mrs.app.room;

import java.time.LocalDate;
import java.util.List;

import mrs.domain.model.ReservableRoom;
import mrs.domain.service.room.RoomService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("rooms")
public class RoomsController {
	@Autowired
	RoomService roomService;
	
	@RequestMapping(method = RequestMethod.GET)
	String listRooms(Model model)
		LocalDate today = LocalDate.now();
		List<ReservableRoom> rooms = roomService.findReservableRooms(today);
		model.addAttribute("date", today);
		model.addAttribute("rooms", rooms);
		return "room/listRooms";
}

-> ん? ControllerのRequestMappingでクエリ検索してる?

/main/resources/templates/room/listRooms.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title th:text="|${#temporals.format(date, 'yyyy/M/d')}の会議室|">2021/01/29の会議室</title>
</head>
<body>
<h3>会議室</h3>
<a th:href="@{'/rooms/' + ${date.minusDays(1)}}">&lt; 前日</a>
<span th:text="|${#temporals.format(date, 'yyyy/M/d')}の会議室|">2021/01/29の会議室</span>
<a th:href="@{'/rooms/' + ${date.plusDays(1)}}">翌日 &gt;</a>

<ul>
	<li th:each="room: ${rooms}">
		<a th:href="@{'/reservations/' + ${date}+ '/' + ${room.meetingRoom.roomId}}"
		 th:text="${room.meetingRoom.roomName}"></a>
	</li>
</ul>
</body>
</html>

-> thymeleafはthで変数入れてますね。th:eachはforeachっぽい。

RoomsController

	String listRooms(@DateTimeFormat(iso = DateTimeFormat.ISO.DATE) @PathVariable("date") LocalDate date, Model model)

規約が多い印象だが、想像してたより複雑ではなさそう。。

[Spring Boot][java] app開発1

STS4 -> File -> Spring Starter Project


SQL: JPA, PostgreSQL
Template Engines: Thymeleaf
Web: Web

ドメイン層: Model, Repository, Service
アプリケーション層: Controller, View(HTML)

# postgresでデータベース作成
$ createdb test -O root

Spring Bootの設定はapplication.propertiesに集約されている
application.properties

spring.jpa.database=POSTGRESQL
spring.datasource.url=jdbc:postgresql://localhost:5432/test
spring.datasource.username=root
spring.datasource.password=hoge
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.properties.hibernate.format_sql=true
spring.datasource.sql-script-encoding=UTF-8
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

# ライブラリ追加

		<dependency>
			<groupId>org.thymeleaf.extras</groupId>
			<artifactId>thymeleaf-extras-java8time</artifactId>
			<scope>2.1.0.RELEASE</scope>
		</dependency>

モデルの配下にエンティティを作成していく
User.java

package mrs.domain.model;

import java.io.Serializable;

import javax.persistence.*;

@Entity
@Table(name="usr")
public class User implements Serializable {
	@Id
	private String userId;
	private String password;
	private String firstName;
	private String lastName;
	
	@Enumerated(EnumType.STRING)
	private RoleName roleName;
}

RoleName.java

package mrs.domain.model;

public enum RoleName {
	ADMIN, USER
}

MeetingRoom.java

package mrs.domain.model;

import java.io.Serializable;

import javax.persistence.*;

@Entity
public class MeetingRoom implements Serializable {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer roomId;
	
	private String roomName;
}

ReservableRoom.java

package mrs.domain.model;

import java.io.Serializable;

import javax.persistence.*;

@Entity
public class ReservableRoom implements Serializable {
	@EmbeddedId
	private ReservableRoomId reservableRoomId;
	
	@ManyToOne
	@JoinColumn(name="room_id", insertable=false, updatable= false)
	@MapsId("roomId")
	private MeetingRoom meetingRoom;
	
	public ReservableRoom(ReservableRoomId reservableRoomId) {
		this.reservableRoomId = reservableRoomId;
	}
	public ReservableRoom() {
		
	}
}

ReservedRoomId.java

package mrs.domain.model;

import java.io.Serializable;
import java.time.LocalDate;

import javax.persistence.Embeddable;

@Embeddable
public class ReservableRoomId implements Serializable {
	
	private Integer roomId;
	private LocalDate reservedDate;
	
	public ReservableRoomId(Integer roomId, LocalDate reservedDate) {
		this.roomId = roomId;
		this.reservedDate = reservedDate;
	}
	
	public ReservableRoomId() {
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((reservedDate == null)? 0 : reservedDate.hashCode());
		result = prime * result + ((roomId == null) ? 0 : roomId.hashCode());
		return result;
	}
	
	@Override
	public boolean equals(Object obj) {
		if(this == obj) return true;
		if(obj == null) return false;
		
		if(getClass() != obj.getClass()) return false;
		ReservableRoomId other = (ReservableRoomId) obj;
		if(reservedDate == null) {
			if(other.reservedDate != null) return false;
		} else if (!reservedDate.equals(other.reservedDate))
			return false;
		if(roomId == null) {
			if(other.roomId != null) return false;
		} else if (!roomId.equals(other.roomId))
			return false;
		return false;
	}
}

Reservation.java

package mrs.domain.model;

import java.io.Serializable;
import time.LocalTime;

import javax.persistence.*;

@Entity
public class Reservation implements Serializable {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer reservationId;
	
	private LocalTime startTime;
	private LocalTime endTime;
	
	@ManyToOne;
	@JoinColumns({@JoinColumn(name = "reserved_date"),
		@JoinColumn(name = "room_id")})
	private RservableRoom reservableRoom;
	
	@ManyToOne
	@JoinColumn(name="user_id")
	private User user;
}

[postgres] macにインストール

Spring Boot

$ postgres –version
-bash: postgres: command not found
$ brew search postgresql
==> Formulae
postgresql postgresql@11 postgresql@9.4 postgresql@9.6
postgresql@10 postgresql@12 postgresql@9.5
==> Casks
navicat-for-postgresql

最新版をインストールします。
$ brew install postgresql
To have launchd start postgresql now and restart at login:
brew services start postgresql
Or, if you don’t want/need a background service you can just run:
pg_ctl -D /usr/local/var/postgres start

$ postgres –version
postgres (PostgreSQL) 13.1
$ pg_ctl -D /usr/local/var/postgres start

# ユーザ作成
$ createuser -P root
# データベース作成
$ createdb test -O root
$ psql -l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
———–+——-+———-+———+——-+——————-
postgres | mac | UTF8 | C | C |
template0 | mac | UTF8 | C | C | =c/mac +
| | | | | mac=CTc/mac
template1 | mac | UTF8 | C | C | =c/mac +
| | | | | mac=CTc/mac
test | root | UTF8 | C | C |
(4 rows)

-> “test”が作成された

### psqlログイン
$ psql -U root test
psql (13.1)
Type “help” for help.

test=>

なんか異常にシンプルやなー

[Spring Boot][java] データアクセス

pom.xml

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<scope>runtime</scope>
		</dependency>

jdbcTemplate使用
MessagesController.java

package com.example.demo;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("messages")
public class MessagesController {
	@Autowired
	JdbcTemplate jdbcTemplate;
	
	@RequestMapping(method = RequestMethod.GET)
	public List<Message> getMessages(){
		return jdbcTemplate.query("SELECT text FROM messages ORDER BY id", (rs, i)->{
			Message m = new Message();
			m.setText(rs.getString("text"));
			return m;
		});
	}
	
	@RequestMapping(method = RequestMethod.POST)
	public Message postMessage(@RequestBody Message message) {
		jbdcTemplate.update("INSERT INTO messages(text) VALUES (?)", message.getText());
		
	}
}

spring bootはクラスパス直下にschema.sqlが存在すると、起動時にそのsqlを実行する

CREATE TABLE messages (
	id INT PRIMARY KEY AUTO_INCREMENT,
	text VARCHAR(255)
);

### PostgreSQLを使う方法

		<dependency>
			<groupId>org.postgresql</groupId>
			<artifactId>postgresql</artifactId>
			<scope>runtime</scope>
		</dependency>

application.properties

string.datasource.username=root
string.datasource.password=hoge
spring.datasource.url=jdbc:postgresql://localhost:5432/spring

mysqlを使用する場合は、schema.sqlを用意するのが定石か

[Spring Boot][java] RESTfulのサンプル作成

Message.java

import java.io.Serializable;

public class Message implements Serializable {
	private String text;
	
	public String getText() {
		return text;
	}
	
	public void setText(String text) {
		this.text = text;
	}
}

MessagesController.java

package com.example.demo;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("messages")
public class MessagesController {
	final List<Message> messages = new CopyOnWriteArrayList<>();
	
	@RequestMapping(method = RequestMethod.GET)
	
	public List<Message> getMessages(){
		return messages;
	}
	
	@RequestMapping(method = RequestMethod.POST)
	public Message postMessages(@RequestBody Message message) {
		messages.add(message);
		return message;
	}
}

### 画面遷移型アプリケーション
テンプレートエンジンとの連携ライブラリ(Starterプロジェクト、AutoConfigure)が用意
– Tymeleaf, FreeMarker, Groovy templates, Velocity, Mustacheなど

Tymeleafを使用する
pom.xml

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>

HelloController.java

package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloController {
	@RequestMapping("/hello")
	public String hello(Model model) {
		model.addAttribute("hello", "Hello World!");
		return "hello";
	}
}

/src/main/resources/templates/hello.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
	<meta charset="UTF-8" />
	<title></title>
</head>
<body>
	<p>
		<span th:text="${hello}">Hello!</span>
	</p>
</body>

src/main/resources

[Spring Boot][java] getting started

やっときました。Spring Boot。
まず、Spring Initializrを使います。
dependenciesに「Web」と入力します。

demo.zipをdownloadします。
STSでfile->import->maven->existing maven projects

DemoApplication.java

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}
}

Run As -> Java ApplicationでTomcatが起動する

2021-01-28 22:00:38.906 INFO 6756 — [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-01-28 22:00:38.906 INFO 6756 — [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1111 ms
2021-01-28 22:00:39.057 INFO 6756 — [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService ‘applicationTaskExecutor’
2021-01-28 22:00:39.219 INFO 6756 — [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ”

controllerの機能を実装する

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication {

	@RequestMapping("/")
	String hello() {
		return "Hello World";
	}
	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

}

Web server failed to start. Port 8080 was already in use.

$ lsof -i:8080
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 6756 mac 41u IPv6 * 0t0 TCP *:http-alt (LISTEN)

src/main/resources/application.properties

server.port=8090

やべ、ちょっと感動した。
– MVC自動設定、Tomcat自動設定、CharacterEncodingFilter自動設定、Logback自動設定、Bean Validation自動設定

Amazon, 楽天, Yahooのショッピングカートの送料のアルゴリズム

Amazon, 楽天, Yahooのショッピングカートの送料のアルゴリズムを確認したい。

### Amazon
商品ごとに送料が計算され、合計金額で合計の送料が計算される

### 楽天
商品ごとに送料計算

### Yahoo Shopping
商品ごとに送料があり、注文手続きの際に、合計金額と合計送料を計算

なるほど、送料は基本商品ごとに持っていて、単純に合計するのね。
同じ会社の商品の場合の計算方法がよくわからん。例えば、A社から送料300円の商品Bと商品Cを購入した時って、送料600円にならないよね。。

うーむ。つまり、商品ごとに送料を持っていて、同じ会社から複数商品を買った場合は、計算処理してるってことね。

[WordPress][vagrant] オリジナルテーマ作成手順5

固定ページ(page.php)をコピーしてsingle.phpを作ります。

single.php

<?php get_header(); ?>
<!-- 上記が追記するコード -->
	<?php if(have_posts()):
		while(have_posts()): the_post();?>
 <section id="content">
	<div class="main">
	<h1><?php the_title(); ?></h1>
	<?php the_content(); ?>
	</div>
 </section>
<?php endwhile;
	endif;?>
 <!-- 下記が追記するコード -->
<?php get_footer(); ?>

### 日付別表示
date.php -> archive.php -> index.php

archive.php

<?php get_header(); ?>
<!-- 上記が追記するコード -->
 <section id="content">
	<div class="main">
      <?php 
      if ( have_posts() ) :
          while ( have_posts() ) : the_post();
      ?>
          <h2>
            <a href="<?php echo get_permalink(); ?>"><?php the_title(); ?></a>
          </h2>
          <section>
            <p>作成日時:<?php the_time('Y年n月j日'); ?></p>
            <a href="<?php echo get_permalink(); ?>"><?php the_excerpt(); ?></a>
          </section>
          <hr>
      <?php 
          endwhile;
      endif;
      ?>
	</div>
 </section>
 <!-- 下記が追記するコード -->
<?php get_footer(); ?>

固定ページやニュースの更新の作り方がなんとなくわかった。
ちょっとノウハウ入りそうだけど、自由にメンテナンスできるのは良いね。

[WordPress][vagrant] オリジナルテーマ作成手順4

作成手順3の続きです。
テンプレートには「優先順位」があり、優先度の高いテンプレートが優先的に使われる。
front-page.php->home.php->index.php

固定ページ
カスタムテンプレート -> page-{スラッグ名}.php -> page-{ID}.php -> page.php -> index.php

投稿ページ
single-{post-type}.php -> single.php -> index.php

### 固定ページの作り方
page.phpを作ります。

<?php get_header(); ?>
<!-- 上記が追記するコード -->
 <section id="content">
	<div class="main">
	<h1></h1>
	</div>
 </section>
 <!-- 下記が追記するコード -->
<?php get_footer(); ?>

classic editorをinstallして昔のエディタに直します。

管理画面の内容が反映されるように、page.phpを回収

<?php get_header(); ?>
<!-- 上記が追記するコード -->
 <section id="content">
	<div class="main">
	<h1><?php the_title(); ?></h1>
	<?php the_content(); ?>
	</div>
 </section>
 <!-- 下記が追記するコード -->
<?php get_footer(); ?>

管理画面で設定した内容が簡単に反映されるようになる。

続いて、投稿ページを作成していきたい。