HBLOG - Creación de nuestro primer blog. Parte - I

carles
Posts: 20
Joined: Thu Dec 19, 2019 7:08 pm

HBLOG - Creación de nuestro primer blog. Parte - I

Post by carles » Mon Mar 09, 2020 8:21 pm

-------------------------------------------------------------------------------------------------------------------------
Añadido al post por apais:

IMPORTANTE: PRE-REQUISITOS:

Esta aplicación será hecha usando la lib Mercury y siguiendo las pautas de desarrollo MVC.
Para eso Apache necesita unas modificaciones que permitan reescribir url, ademas de las habituales para ejecutar mod_harbour.

En httpd.conf:
1) Asegúrate de descomentar (activar) mod_rewrite

2) En la seción:
<Directory "${SRVROOT}/htdocs">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
asegúrate que AllowOverride tenga el valor "All"
--------------------------------------------------------------------------------------------------------------------------

Hola,

Lo prometido es deuda. Vamos a crear un blog hasta donde vosotros querais, paso a paso. La idea es aprender a crear una aplicacion siguiendo la arquitectura MVC, que os ayudará a asimilar esta técnica para construir vuestras futuras aplicaciones de manera profesional.

Quedamos en que a partir de un concepto de blog basico mirariamos de crearlo de manera sencillo y partiendo de 0. No vamos de entrada a usar grandes templates hechos ni nada parecido. De nada sirve hacer copy/paste de templates de la red si no entendeis el mecanismo de programación. Todo el tema de maquetaje ya llegará mas tarde si avanzamos.

Partimos de la base de que tiene el blog mas sencillo que podemos hacer y basicamente apareció esto

Image

La idea es que el blog nos muestre entradas y podamos avanzar/retroceder entre ellas. Asi pues el primer ejercicio es crear la estructura del proyecto e intentar que mod harbour nos devuelva los 5 primeros registros y un boton al final para pedir 5 ejercicios mas

Image

Ahhh lo mas importante hasta ahora. Lo haremos todo en formato texto, el objetivo es aprender a entender esta programacion ;-)

Todo el código está en el repositorio https://github.com/carles9000/hblog , podeis hacer un clone o directamente un download. El proyecto lo llamaremos hblog.

Crearemos una tabla hiper-basica con los siguientes campos: id, fecha,titulo, texto

Si os acordais cuando empezamos , el concepto MVC es elsiguiente

Image

Una de las particularidades del sistema es que todas las peticiones que se hagan a nuestro programa pasaarn siempre por nuestro fichero principal, generalmente será index.prg

Es por eso que podemos necesitamos activar en apache el mod_rewrite porque entre otras se encargará de redirigir siempre a index.prg

En este primer diseño, tendremos


index.prg --> Crearemos el objeto App() que nos permitira crear los diferentes “enrutados” a nuestra aplicación.
src/controller/rootcontroller.prg --> Primer controlador que creamos, que se encargará de procesar las peticiones base -> localhost/hblog/
src/model/entry.prg --> Modelo que se encargará de abrir la tabla y un metodo de momento para cargar registros
src/view/root.view --> Primera super vista que nos mostrará la primera pantalla con los registros y el button para avanzar


Y este es el resultado

Image

Éxito total !!! Ya tenemos nuestro primer blog (el blog mas feo de la historia,jajaja)

Como podeis apreciar el boton crea una peticion y habeis de entender todo el flujo que se producirá:

Entrará por index.prg
Lo enrutara hacie el controller rootcontroller que “escuchara que quiere hacer” y abrirar la tabla de datos y cargar los datos
Llamara a la vista y le pasará los datos para que los pinte y los devuelva al navegador

Y eso es todo.

Ahor se trata de que intenteis a parte de entender todo el proceso, amplicar la funcionalidad, por ejemplo poniendo el boton de “pagina atrás”, “Top”, “Bottom”

Todo la explicación paso a paso esta en el video --> https://youtu.be/g7Fjk9BbZ24

Una vez realizado el ejercicio lo he subido al servidor y sin tocar nada ha salido andando

Podeis probarlo en --> https://54.37.60.33/hblog/


Y aquí en el foro dejaremos dudas a esta primer parte del taller.

Saludos.
C.

Cesar_SCS
Posts: 5
Joined: Tue Nov 26, 2019 5:09 pm

Re: HBLOG - Creación de nuestro primer blog. Parte - I

Post by Cesar_SCS » Mon Mar 09, 2020 8:40 pm

Muy buena tu explicación inicial Charly, gracias.

carles
Posts: 20
Joined: Thu Dec 19, 2019 7:08 pm

Re: HBLOG - Creación de nuestro primer blog. Parte - I

Post by carles » Tue Mar 10, 2020 8:30 am

Cesar,

Gracias ! :-). Mirad de crear el otro boton para retroceder 5 registros y seguimos...


C.

Cesar_SCS
Posts: 5
Joined: Tue Nov 26, 2019 5:09 pm

Re: HBLOG - Creación de nuestro primer blog. Parte - I

Post by Cesar_SCS » Wed Mar 11, 2020 8:37 am

Los que han bajado la contribucion de Wilson,
despues de buscar seria bueno poner un boton refresh()
para regresar al estado Actual del hblog ?

saludos.

wilsongamboa
Posts: 16
Joined: Tue Nov 26, 2019 1:38 pm

Re: HBLOG - Creación de nuestro primer blog. Parte - I

Post by wilsongamboa » Wed Mar 11, 2020 8:53 am

ya están los botones como subo los fuentes no se GIT ni tampoco como subir
perdón la ..
gracias

wilsongamboa
Posts: 16
Joined: Tue Nov 26, 2019 1:38 pm

Re: HBLOG - Creación de nuestro primer blog. Parte - I

Post by wilsongamboa » Wed Mar 11, 2020 8:58 am

rootcontroler.prg

Code: Select all

//----------------------------------------------------------------------------//

CLASS RootController

    data cSearch     init ''
    data nRegGrande  init 10000000

    METHOD New( oController )

    METHOD Next( oController )  

    METHOD prev( oController )  
    
    METHOD gotop( oController ) 

    METHOD gobottom( oController )  

    METHOD search( oController )    

    METHOD Default( oController )  

ENDCLASS    

//----------------------------------------------------------------------------//

METHOD New( oController ) CLASS RootController

    local cAction := oController:oRequest:Post( 'action' )
    local cSearch := oController:oRequest:Post( 'search' )

    ::cSearch = cSearch

    ? 'Action => ', cAction
    ? 'var    => ', cSearch 
	
    do case
       case cAction == "Next"   	; ::Next( oController )
       case cAction == "prev"   	; ::prev( oController )
       case cAction == "gotop"   	; ::gotop( oController )
       case cAction == "gobottom"   ; ::gobottom( oController )
       case cAction == "buscar"   	; ::search( oController )

       otherwise
          ::Default( oController ) 
		  
    endcase

return Self    

//----------------------------------------------------------------------------//

METHOD Default( oController ) CLASS RootController

   local oModelEntry 	:= EntryModel():New()   
   local hData 		    := oModelEntry:Rows( nil, 5 )   

   oController:View( "root.view", hData )

RETU nil 

METHOD Next( oController ) CLASS RootController  

	local oModelEntry   := EntryModel():New() 
	local nRecno 		:= oController:oRequest:Post( 'recno', 0, 'N' )
	local hData 		:= oModelEntry:Rows( nRecno, 5 )

	oController:View( "root.view", hData )
	
RETU NIL

METHOD prev( oController ) CLASS RootController  

	local oModelEntry   := EntryModel():New() 
	local nRecno 		:= oController:oRequest:Post( 'recno', 0, 'N' )
	local hData 		:= oModelEntry:Rows( nRecno, -5 )

	oController:View( "root.view", hData )
	
RETU NIL


METHOD gotop( oController ) CLASS RootController  

	local oModelEntry   := EntryModel():New() 
	local nRecno 		:= 0 
	local hData 		:= oModelEntry:Rows( nRecno, 5 )

	oController:View( "root.view", hData )
	
RETU NIL

METHOD search( oController ) CLASS RootController  

	local oModelEntry   := EntryModel():New() 
	local hData 		:= oModelEntry:search( ::cSearch  )

	oController:View( "root.view", hData )
	
RETU NIL

METHOD gobottom( oController ) CLASS RootController  

	local oModelEntry   := EntryModel():New() 
	local nRecno 		:= ::nRegGrande 
	local hData 		:= oModelEntry:Rows( nRecno, 5 )



	oController:View( "root.view", hData )
	
RETU NIL



{% zinclude( "/src/model/entry.prg" ) %}
entry.prg

Code: Select all

//----------------------------------------------------------------------------//

CLASS EntryModel 

	DATA cAlias
	DATA nRegGrande init 10000000

	METHOD New()             		CONSTRUCTOR
	METHOD search( cSearch )
	METHOD Rows( nId, nRows )
	
ENDCLASS

//----------------------------------------------------------------------------//

METHOD New() CLASS EntryModel

	
	USE ( AppPathData() + 'entry.dbf' ) SHARED NEW VIA 'DBFCDX'
	SET INDEX TO 'entry.cdx'
	
	::cAlias := Alias()		

RETU SELF

METHOD search( cSearch ) CLASS EntryModel

	LOCAL hData 	:= {=>}
	LOCAL hRows 	:= {}
	LOCAL nCount 	:= 0
	LOCAL nRecno
   
	cSearch = lower( alltrim( cSearch ) )

	select ( ::cAlias )
	( ::cAlias )->( dbgotop() )
	locate for ( hb_WildMatch( "*"+cSearch+ "*", lower( ( ::cAlias )->titulo ) )  .or. ;
	             hb_WildMatch( "*"+cSearch+ "*", lower( ( ::cAlias )->texto  ) ) ) ;
			     .and. !( ::cAlias )->( eof() ) 

	while ( ::cAlias )->( found() )

		nRecno := (::cAlias)->( Recno() )
		Aadd( hRows, { '_recno'	=> nRecno,;
						'id' 		=> (::cAlias)->id,;
						'fecha'		=> (::cAlias)->fecha,;
						'titulo'	=> (::cAlias)->titulo,;
						'texto' 	=> (::cAlias)->texto ;
					})						
	
		nCount++						
		select ( ::cAlias )
		continue
	end		

	hData[ 'recno' ] := nRecno
	hData[ 'rows'  ] := hRows

RETU hData


METHOD Rows( nId, nRows ) CLASS EntryModel

	LOCAL hData 	:= {=>}
	LOCAL hRows 	:= {}
	LOCAL nCount 	:= 0
	LOCAL nRecno

	DEFAULT nId 		 TO 0
	DEFAULT nRows		 TO 5
	
	IF nId == 0
		(::cAlias)->( DbGoTop() )
	ELSEIF nId == ::nRegGrande	
		(::cAlias)->( DbGoBottom() )
		(::cAlias)->( DbSkip( -nRows ) )
		if (::cAlias)->( bof() )
			(::cAlias)->( DbGotop() )
		else
			(::cAlias)->( dbskip() )	
		end 	
	ELSE
		if nRows < 0
			(::cAlias)->( DbGoto( nId ) )
			(::cAlias)->( DbSkip( nRows ) )
			if (::cAlias)->( bof() )
				(::cAlias)->( dbgotop() )
			else
				( ::cAlias )->( dbskip( -1 ) )	
			end 
			nRows = abs( nRows )	
		else	
			(::cAlias)->( DbGoto( nId ) )
			(::cAlias)->( DbSkip() )
		end 	
	ENDIF
	
		WHILE nCount < nRows .AND. (::cAlias)->( !Eof() )
		
			nRecno := (::cAlias)->( Recno() )
		
			Aadd( hRows, { '_recno'	=> nRecno,;
							'id' 		=> (::cAlias)->id,;
							'fecha'		=> (::cAlias)->fecha,;
							'titulo'	=> (::cAlias)->titulo,;
							'texto' 	=> (::cAlias)->texto ;
						})						
		
			nCount++						
		
			(::cAlias)->( DbSkip(1) )
		END	
		
	
	
	hData[ 'recno' ] := nRecno
	hData[ 'rows'  ] := hRows

RETU hData
root.view

Code: Select all

<html>

	<h3>My first blog...</h3><hr>

	<?prg
		LOCAL hData 	:= PValue(1)
		LOCAL cHtml 	:= ''
		LOCAL nI
		
		FOR nI := 1 TO len( hData[ 'rows' ] )
			cHtml += valtochar( hData[ 'rows'][ nI ] ) + '<br>'
		NEXT
	  
	    retu cHtml
	?>
	
	<br>Last Recno = {{ PARAM 1, 'recno' }} 
	
	<form action="{{ Route( 'root' ) }}" method="POST">
		<input type="hidden" name="recno" value="{{ PARAM 1, 'recno' }}">		
		<input type="submit" name="action" value="prev" >
		<input type="submit" name="action" value="Next" >
		<input type="submit" name="action" value="gotop" >
		<input type="submit" name="action" value="gobottom" >
		<input type="submit" name="action" value="buscar" >
		<input type="search" id="buscar" name="search">

	</form>
	
</html>
saludos
Wilson

wilsongamboa
Posts: 16
Joined: Tue Nov 26, 2019 1:38 pm

Re: HBLOG - Creación de nuestro primer blog. Parte - I

Post by wilsongamboa » Wed Mar 11, 2020 6:31 pm

Image[/img]

wilsongamboa
Posts: 16
Joined: Tue Nov 26, 2019 1:38 pm

Re: HBLOG - Creación de nuestro primer blog. Parte - I

Post by wilsongamboa » Wed Mar 11, 2020 6:32 pm

Image

Cesar_SCS
Posts: 5
Joined: Tue Nov 26, 2019 5:09 pm

Re: HBLOG - Creación de nuestro primer blog. Parte - I

Post by Cesar_SCS » Wed Mar 11, 2020 6:47 pm

comentario de Charly en el slack

Por cierto....en el metodo buscar de wilson si le das a buscar en blanco te aparecen todos....

el next si pasas del ultimo registro no deberia quedarse la pagina en blanco.

en el caso 1, si el cSearh esta vacio habria que regresar un registro con un mensaje.

Code: Select all

if ! empty( cSearch )
    * procesa la busqueda
else
               nRecno := 0
		Aadd( hRows, { '_recno'	=> nRecno,;
						'id' 		=> "",;
						'fecha'		=> date(),;
						'titulo'	=> "error",;
						'texto' 	=> "Busqueda no efectuada" ;
					})						
endif

pero tambien validar cuando no encuentre nada.

saludos.

carles
Posts: 20
Joined: Thu Dec 19, 2019 7:08 pm

Re: HBLOG - Creación de nuestro primer blog. Parte - I

Post by carles » Fri Mar 13, 2020 9:05 am

Buenas,

He probado el code de Wilson -> Bravo :D , ajustaremos unas detallitos y quedara de lujo

Cesar -> Quizas mejor que un mensaje, si entramos a buscar en blanco...q no haga nada, no ? pero como lo resolvemos...


Lo vemos...

Post Reply